コード例 #1
0
    def patch(self):
        """Update of contract
        """
        if self.request.validated['tender_status'] not in ['active', 'complete']:
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        data = self.request.validated['data']
        if self.request.context.status == 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) status'.format(self.request.context.status))
            self.request.errors.status = 403
            return
        if self.request.context.status != 'active' and 'status' in data and data['status'] == 'active':
            tender = self.request.validated['tender']
            award = [a for a in tender.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

        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' and self.request.context.status != 'active':
            self.request.errors.add('body', 'data', 'Can\'t update contract status')
            self.request.errors.status = 403
            return

        check_tender_status(self.request)
        if save_tender(self.request):
            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()}
コード例 #2
0
 def patch(self):
     """Post a cancellation resolution
     """
     tender = self.request.validated['tender']
     if tender.status in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update cancellation in current ({}) tender status'.
             format(tender.status))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active' for i in tender.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_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")}
コード例 #3
0
 def patch(self):
     """Post a complaint resolution
     """
     tender = self.request.validated['tender']
     if tender.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 ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     if self.request.context.status != 'pending':
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) status'.format(self.request.context.status))
         self.request.errors.status = 403
         return
     if self.request.validated['data'].get('status', self.request.context.status) == 'cancelled':
         self.request.errors.add('body', 'data', 'Can\'t cancel complaint')
         self.request.errors.status = 403
         return
     apply_patch(self.request, save=False, src=self.request.context.serialize())
     if self.request.context.status == 'resolved' and tender.status != 'active.enquiries':
         for i in tender.complaints:
             if i.status == 'pending':
                 i.status = 'cancelled'
         [setattr(i, 'status', 'cancelled') for i in tender.lots]
         tender.status = 'cancelled'
     elif self.request.context.status in ['declined', 'invalid'] and tender.status == 'active.awarded':
         check_tender_status(self.request)
     if save_tender(self.request):
         LOGGER.info('Updated tender complaint {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_complaint_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #4
0
    def patch(self):
        """Update of contract
        """
        if self.request.validated['tender_status'] not in ['active']:
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        if self.request.context.status == 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) status'.format(self.request.context.status))
            self.request.errors.status = 403
            return

        data = self.request.validated['data']
        if self.request.context.status != 'active' and 'status' in data and data['status'] == 'active':
            tender = self.request.validated['tender']
            award = [a for a in tender.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
            if any([
                i.status in tender.block_complaint_status and a.lotID == award.lotID
                for a in tender.awards
                for i in a.complaints
            ]):
                self.request.errors.add('body', 'data', 'Can\'t sign contract before reviewing all complaints')
                self.request.errors.status = 403
                return

        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 self.request.validated['tender'].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 less or equal to awarded amount ({})'.format(award.value.amount))
                self.request.errors.status = 403
                return

        contract_status = self.request.context.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())
        self.request.context.date = get_now()
        if contract_status != self.request.context.status and contract_status != 'pending' and 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_tender_negotiation_status(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()}
コード例 #5
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.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)}
コード例 #6
0
ファイル: tender.py プロジェクト: Vanuan/openprocurement.api
    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.request.validated['tender']
        if tender.status in ['complete', 'unsuccessful', 'cancelled']:
            self.request.errors.add('body', 'data', 'Can\'t update tender in current status')
            self.request.errors.status = 403
            return
        apply_patch(self.request, src=self.request.validated['tender_src'])
        return {'data': tender.serialize(tender.status)}
コード例 #7
0
 def patch(self):
     """Post a complaint resolution for award
     """
     tender = self.request.validated["tender"]
     if tender.status not in ["active.qualification", "active.awarded"]:
         self.request.errors.add(
             "body", "data", "Can't update complaint in current ({}) tender status".format(tender.status)
         )
         self.request.errors.status = 403
         return
     complaint = self.request.context
     if complaint.status != "pending":
         self.request.errors.add(
             "body", "data", "Can't update complaint in current ({}) status".format(complaint.status)
         )
         self.request.errors.status = 403
         return
     apply_patch(self.request, save=False, src=complaint.serialize())
     if complaint.status == "cancelled":
         self.request.errors.add("body", "data", "Can't cancel complaint")
         self.request.errors.status = 403
         return
     if complaint.status == "resolved":
         award = self.request.validated["award"]
         if tender.status == "active.awarded":
             tender.status = "active.qualification"
             tender.awardPeriod.endDate = None
         if award.status == "unsuccessful":
             for i in tender.awards[tender.awards.index(award) :]:
                 i.complaintPeriod.endDate = get_now() + STAND_STILL_TIME
                 i.status = "cancelled"
                 for j in i.complaints:
                     if j.status == "pending":
                         j.status = "cancelled"
         for i in award.contracts:
             i.status = "cancelled"
         award.complaintPeriod.endDate = get_now() + STAND_STILL_TIME
         award.status = "cancelled"
         add_next_award(self.request)
     elif complaint.status in ["declined", "invalid"] and tender.status == "active.awarded":
         pending_complaints = [i for i in tender.complaints if i.status == "pending"]
         pending_awards_complaints = [i for a in tender.awards for i in a.complaints if i.status == "pending"]
         stand_still_ends = [a.complaintPeriod.endDate for a in tender.awards if a.complaintPeriod.endDate]
         stand_still_end = max(stand_still_ends) if stand_still_ends else get_now()
         stand_still_time_expired = stand_still_end < get_now()
         if not pending_complaints and not pending_awards_complaints and stand_still_time_expired:
             active_awards = [a for a in tender.awards if a.status == "active"]
             if not active_awards:
                 tender.status = "unsuccessful"
     if save_tender(self.request):
         LOGGER.info(
             "Updated tender award complaint {}".format(self.request.context.id),
             extra={"MESSAGE_ID": "tender_award_complaint_patch"},
         )
         return {"data": complaint.serialize("view")}
コード例 #8
0
 def patch(self):
     """Post a complaint resolution for award
     """
     tender = self.request.validated["tender"]
     if tender.status not in ["active.qualification", "active.awarded"]:
         self.request.errors.add(
             "body", "data", "Can't update complaint in current ({}) tender status".format(tender.status)
         )
         self.request.errors.status = 403
         return
     if any([i.status != "active" for i in tender.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
     complaint = self.request.context
     if complaint.status != "pending":
         self.request.errors.add(
             "body", "data", "Can't update complaint in current ({}) status".format(complaint.status)
         )
         self.request.errors.status = 403
         return
     if self.request.validated["data"].get("status", complaint.status) == "cancelled":
         self.request.errors.add("body", "data", "Can't cancel complaint")
         self.request.errors.status = 403
         return
     apply_patch(self.request, save=False, src=complaint.serialize())
     if complaint.status == "resolved":
         award = self.request.validated["award"]
         if tender.status == "active.awarded":
             tender.status = "active.qualification"
             tender.awardPeriod.endDate = None
         now = get_now()
         if award.status == "unsuccessful":
             for i in tender.awards[tender.awards.index(award) :]:
                 if i.lotID != award.lotID:
                     continue
                 i.complaintPeriod.endDate = now + STAND_STILL_TIME
                 i.status = "cancelled"
                 for j in i.complaints:
                     if j.status == "pending":
                         j.status = "cancelled"
         for i in tender.contracts:
             if award.id == i.awardID:
                 i.status = "cancelled"
         award.complaintPeriod.endDate = now + STAND_STILL_TIME
         award.status = "cancelled"
         add_next_award(self.request)
     elif complaint.status in ["declined", "invalid"] and tender.status == "active.awarded":
         check_tender_status(self.request)
     if save_tender(self.request):
         LOGGER.info(
             "Updated tender award complaint {}".format(self.request.context.id),
             extra=context_unpack(self.request, {"MESSAGE_ID": "tender_award_complaint_patch"}),
         )
         return {"data": complaint.serialize("view")}
コード例 #9
0
 def patch(self):
     """Post a cancellation resolution
     """
     tender = self.request.validated['tender']
     if tender.status in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add('body', 'data', 'Can\'t update cancellation in current ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     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):
         LOGGER.info('Updated tender cancellation {}'.format(self.request.context.id), extra={'MESSAGE_ID': 'tender_cancellation_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #10
0
    def patch(self):
        """Plan Edit (partial)

        For example here is how procuring entity can change name:

        .. sourcecode:: http

            PATCH /plans/62179f8f94a246239268750a6eb0e53f HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "procuringEntity": {
                        "identifier": {
                            "legalName": "ДП Державне Уравління Справами11"
                        },
                        "name": "ДУС"
                    },
                    "budget": {
                        "project": {
                            "name": "proj_name",
                            "id": "proj_id"
                        },
                        "amount": 10020,
                        "amountNet": 22222,
                        "id": "budget_id",
                        "description": "budget_description"
                    }
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

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

        """
        plan = self.request.validated['plan']
        apply_patch(self.request,
                    save=False,
                    src=self.request.validated['plan_src'])
        save_plan(self.request)
        LOGGER.info('Updated plan {}'.format(plan.id),
                    extra=context_unpack(self.request,
                                         {'MESSAGE_ID': 'plan_patch'}))
        return {'data': plan.serialize('view')}
コード例 #11
0
    def patch(self):
        """Post a qualification resolution
        """
        def set_bid_status(tender, bid_id, status, lotId=None):
            if lotId:
                for bid in tender.bids:
                    if bid.id == bid_id:
                        for lotValue in bid.lotValues:
                            if lotValue.relatedLot == lotId:
                                lotValue.status = status
                                return bid
            for bid in tender.bids:
                if bid.id == bid_id:
                    bid.status = status
                    return bid
        tender = self.request.validated['tender']
        if tender.status not in ['active.pre-qualification']:
            self.request.errors.add('body', 'data', 'Can\'t update qualification in current ({}) tender status'.format(tender.status))
            self.request.errors.status = 403
            return
        if self.request.context.status == 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update qualification in current cancelled qualification status')
            self.request.errors.status = 403
            return

        prev_status = self.request.context.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())
        if prev_status != 'pending' and self.request.context.status != 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update qualification status')
            self.request.errors.status = 403
            return
        if self.request.context.status == 'active':
            # approve related bid
            set_bid_status(tender, self.request.context.bidID, 'active', self.request.context.lotID)
        elif self.request.context.status == 'unsuccessful':
            # cancel related bid
            set_bid_status(tender, self.request.context.bidID, 'unsuccessful', self.request.context.lotID)
        elif self.request.context.status == 'cancelled':
            # return bid to initial status
            bid = set_bid_status(tender, self.request.context.bidID, 'pending', self.request.context.lotID)
            # generate new qualification for related bid
            ids = prepare_qualifications(self.request, bids=[bid], lotId=self.request.context.lotID)
            self.request.response.headers['Location'] = self.request.route_url('TenderCD Qualification',
                                                                               tender_id=tender.id,
                                                                               qualification_id=ids[0])
        if save_tender(self.request):
            self.LOGGER.info('Updated tender qualification {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_qualification_patch'}))
            return {'data': self.request.context.serialize("view")}
コード例 #12
0
    def patch(self):
        """Post a qualification resolution
        """
        def set_bid_status(tender, bid_id, status, lotId=None):
            if lotId:
                for bid in tender.bids:
                    if bid.id == bid_id:
                        for lotValue in bid.lotValues:
                            if lotValue.relatedLot == lotId:
                                lotValue.status = status
                                return bid
            for bid in tender.bids:
                if bid.id == bid_id:
                    bid.status = status
                    return bid
        tender = self.request.validated['tender']
        if tender.status not in ['active.pre-qualification']:
            self.request.errors.add('body', 'data', 'Can\'t update qualification in current ({}) tender status'.format(tender.status))
            self.request.errors.status = 403
            return
        if self.request.context.status == 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update qualification in current cancelled qualification status')
            self.request.errors.status = 403
            return

        prev_status = self.request.context.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())
        if prev_status != 'pending' and self.request.context.status != 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update qualification status'.format(tender.status))
            self.request.errors.status = 403
            return
        if self.request.context.status == 'active':
            # approve related bid
            set_bid_status(tender, self.request.context.bidID, 'active', self.request.context.lotID)
        elif self.request.context.status == 'unsuccessful':
            # cancel related bid
            set_bid_status(tender, self.request.context.bidID, 'unsuccessful', self.request.context.lotID)
        elif self.request.context.status == 'cancelled':
            # return bid to initial status
            bid = set_bid_status(tender, self.request.context.bidID, 'pending', self.request.context.lotID)
            # generate new qualification for related bid
            ids = prepare_qualifications(self.request, bids=[bid], lotId=self.request.context.lotID)
            self.request.response.headers['Location'] = self.request.route_url('TenderEU Qualification',
                                                                               tender_id=tender.id,
                                                                               qualification_id=ids[0])
        if save_tender(self.request):
            self.LOGGER.info('Updated tender qualification {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_qualification_patch'}))
            return {'data': self.request.context.serialize("view")}
コード例 #13
0
 def patch(self):
     """Update of contract
     """
     if self.request.validated['tender_status'] not in ['active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     tender = self.request.validated['tender']
     if any([i.status != 'active' for i in tender.lots if i.id in [a.lotID for a in tender.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 self.request.context.status != 'active' and 'status' in data and data['status'] == 'active':
         award = [a for a in tender.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 tender.complaints
             if i.status in ['claim', 'answered', 'pending'] and i.relatedLot in [None, award.lotID]
         ]
         pending_awards_complaints = [
             i
             for a in tender.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_tender_status(self.request)
     if save_tender(self.request):
         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()}
コード例 #14
0
 def patch(self):
     """Update of contract
     """
     if self.request.validated['tender_status'] not in [
             'active.awarded', 'complete'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update contract in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
     data = self.request.validated['data']
     if self.request.context.status != 'active' and 'status' in data and data[
             'status'] == 'active':
         tender = self.request.validated['tender']
         stand_still_end = max(
             [a.complaintPeriod.endDate for a in tender.awards])
         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 tender.complaints if i.status == 'pending'
         ]
         pending_awards_complaints = [
             i for a in tender.awards for i in a.complaints
             if i.status == 'pending'
         ]
         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
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     if self.request.context.status == 'active' and self.request.validated[
             'tender_status'] != 'complete':
         self.request.validated['tender'].status = 'complete'
     if save_tender(self.request):
         LOGGER.info('Updated tender award contract {}'.format(
             self.request.context.id),
                     extra={'MESSAGE_ID': 'tender_award_contract_patch'})
         return {'data': self.request.context.serialize()}
コード例 #15
0
 def patch(self):
     """Post a complaint resolution
     """
     tender = self.request.validated["tender"]
     if tender.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 ({}) tender status".format(tender.status)
         )
         self.request.errors.status = 403
         return
     if self.request.context.status != "pending":
         self.request.errors.add(
             "body", "data", "Can't update complaint in current ({}) status".format(self.request.context.status)
         )
         self.request.errors.status = 403
         return
     apply_patch(self.request, save=False, src=self.request.context.serialize())
     if self.request.context.status == "cancelled":
         self.request.errors.add("body", "data", "Can't cancel complaint")
         self.request.errors.status = 403
         return
     if self.request.context.status == "resolved" and tender.status != "active.enquiries":
         for i in tender.complaints:
             if i.status == "pending":
                 i.status = "cancelled"
         tender.status = "cancelled"
     elif self.request.context.status in ["declined", "invalid"] and tender.status == "active.awarded":
         pending_complaints = [i for i in tender.complaints if i.status == "pending"]
         pending_awards_complaints = [i for a in tender.awards for i in a.complaints if i.status == "pending"]
         stand_still_ends = [a.complaintPeriod.endDate for a in tender.awards if a.complaintPeriod.endDate]
         stand_still_end = max(stand_still_ends) if stand_still_ends else get_now()
         stand_still_time_expired = stand_still_end < get_now()
         if not pending_complaints and not pending_awards_complaints and stand_still_time_expired:
             active_awards = [a for a in tender.awards if a.status == "active"]
             if not active_awards:
                 tender.status = "unsuccessful"
     if save_tender(self.request):
         LOGGER.info(
             "Updated tender complaint {}".format(self.request.context.id),
             extra={"MESSAGE_ID": "tender_complaint_patch"},
         )
         return {"data": self.request.context.serialize("view")}
コード例 #16
0
 def patch(self):
     """Post an Answer
     """
     tender = self.request.validated['tender']
     if tender.status != 'active.tendering':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update question in current ({}) tender status'.format(
                 tender.status))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active' for i in tender.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
     now = get_now()
     if now > tender.enquiryPeriod.clarificationsUntil:
         self.request.errors.add(
             'body', 'data',
             'Can update question only before enquiryPeriod.clarificationsUntil'
         )
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated tender question {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_question_patch'}))
         return {'data': self.request.context.serialize(tender.status)}
コード例 #17
0
 def patch(self):
     """Tender 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['tender_status'] not in [
             'active.enquiries', 'active.tendering', 'active.auction',
             'active.qualification', 'active.awarded'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_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)
         LOGGER.info('Updated tender complaint document {}'.format(
             self.request.context.id),
                     extra=context_unpack(
                         self.request,
                         {'MESSAGE_ID': 'tender_complaint_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #18
0
 def patch(self):
     """Tender Award Document Update"""
     if self.request.validated['tender_status'] != 'active.qualification':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active'
             for i in self.request.validated['tender'].lots
             if i.id == self.request.validated['award'].lotID
     ]):
         self.request.errors.add(
             'body', 'data',
             'Can update document only in active lot 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 tender award document {}'.format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {'MESSAGE_ID': 'tender_award_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #19
0
 def patch(self):
     """Tender Bid Document Update"""
     if self.request.validated['tender_status'] not in ['active.tendering', 'active.qualification']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if self.request.validated['tender_status'] == 'active.qualification' and not [i for i in self.request.validated['tender'].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['tender_status'] != 'active.tendering' and 'confidentiality' in self.request.validated['data']:
         if self.context.confidentiality != self.request.validated['data']['confidentiality']:
             self.request.errors.add('body', 'data', 'Can\'t update document confidentiality in current ({}) tender status'.format(self.request.validated['tender_status']))
             self.request.errors.status = 403
             return
     bid = getattr(self.context, "__parent__")
     if bid and bid.status in ['invalid', 'unsuccessful', 'deleted']:
         self.request.errors.add('body', 'data', 'Can\'t update document data for \'{}\' bid'.format(bid.status))
         self.request.errors.status = 403
         return
     if self.request.validated['tender_status'] == 'active.tendering':
         self.request.validated['tender'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated tender bid document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #20
0
def patch_auction(request):
    """Set urls for access to auction.
    """
    if apply_patch(request, src=request.validated['tender_src']):
        LOGGER.info('Updated auction urls',
                    extra={'MESSAGE_ID': 'tender_auction_patch'})
        return {'data': request.validated['tender'].serialize("auction_view")}
コード例 #21
0
 def patch(self):
     """Tender Bid Document Update"""
     if self.request.validated['tender_status'] not in [
             'active.tendering', 'active.qualification'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if self.request.validated[
             'tender_status'] == 'active.qualification' and not [
                 i for i in self.request.validated['tender'].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 apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender bid document {}'.format(
             self.request.context.id),
                     extra=context_unpack(
                         self.request,
                         {'MESSAGE_ID': 'tender_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #22
0
 def patch(self):
     """Tender Qualification Document Update"""
     if self.request.validated[
             'tender_status'] != 'active.pre-qualification':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     qualification = self.request.validated['qualification']
     if qualification.status != 'pending':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current qualification 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 tender qualification document {}'.format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {'MESSAGE_ID': 'tender_qualification_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #23
0
 def patch(self):
     """Tender Award Contract Document Update"""
     if self.request.validated['tender_status'] not in [
             'active.awarded', 'complete'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if self.request.validated['contract'].status not in [
             'pending', 'active'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current contract status')
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info(
             'Updated tender award contract document {}'.format(
                 self.request.context.id),
             extra={'MESSAGE_ID': 'tender_award_contract_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #24
0
 def patch(self):
     """Tender Bid Document Update"""
     if self.request.validated["tender_status"] not in ["active.tendering", "active.qualification"]:
         self.request.errors.add(
             "body",
             "data",
             "Can't update document in current ({}) tender status".format(self.request.validated["tender_status"]),
         )
         self.request.errors.status = 403
         return
     if self.request.validated["tender_status"] == "active.qualification" and not [
         i
         for i in self.request.validated["tender"].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 apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info(
             "Updated tender bid document {}".format(self.request.context.id),
             extra=context_unpack(self.request, {"MESSAGE_ID": "tender_bid_document_patch"}),
         )
         return {"data": self.request.context.serialize("view")}
コード例 #25
0
    def patch(self):
        """Update of proposal

        Example request to change bid proposal:

        .. sourcecode:: http

            PATCH /tenders/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.validated['tender_status'] != 'active.tendering':
            self.request.errors.add('body', 'data', 'Can\'t update bid in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        if self.request.authenticated_role != 'Administrator':
            bid_status_to = self.request.validated['data'].get("status", self.request.context.status)
            if bid_status_to != 'pending':
                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['tender'].modified = False
        if apply_patch(self.request, src=self.request.context.serialize()):
            self.LOGGER.info('Updated tender bid {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_bid_patch'}))
            return {'data': self.request.context.serialize("view")}
コード例 #26
0
 def patch(self):
     """Set urls for access to auction for lot.
     """
     if apply_patch(self.request, src=self.request.validated["tender_src"]):
         self.LOGGER.info(
             "Updated auction urls", extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_auction_patch"})
         )
         return {"data": self.request.validated["tender"].serialize("auction_view")}
コード例 #27
0
    def patch(self):
        """Plan Edit (partial)

        For example here is how procuring entity can change name:

        .. sourcecode:: http

            PATCH /plans/62179f8f94a246239268750a6eb0e53f HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "procuringEntity": {
                        "identifier": {
                            "legalName": "ДП Державне Уравління Справами11"
                        },
                        "name": "ДУС"
                    },
                    "budget": {
                        "project": {
                            "name": "proj_name",
                            "id": "proj_id"
                        },
                        "amount": 10020,
                        "amountNet": 22222,
                        "id": "budget_id",
                        "description": "budget_description"
                    }
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

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

        """
        plan = self.request.validated['plan']
        apply_patch(self.request, save=False, src=self.request.validated['plan_src'])
        save_plan(self.request)
        LOGGER.info('Updated plan {}'.format(plan.id),
                    extra=context_unpack(self.request, {'MESSAGE_ID': 'plan_patch'}))
        return {'data': plan.serialize('view')}
コード例 #28
0
 def patch(self):
     """Update of contract
     """
     if self.request.validated['tender_status'] not in ['active.qualification', 'active.awarded', 'complete']:
         self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     tender = self.request.validated['tender']
     if any([i.status != 'active' for i in tender.lots if i.id in [a.lotID for a in tender.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 self.request.context.status != 'active' and 'status' in data and data['status'] == 'active':
         award = [a for a in tender.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 tender.complaints
             if i.status in ['claim', 'answered', 'pending'] and i.relatedLot in [None, award.lotID]
         ]
         pending_awards_complaints = [
             i
             for a in tender.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
     check_tender_status(self.request)
     if save_tender(self.request):
         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()}
コード例 #29
0
    def patch(self):
        """Update of contract
        """
        if self.request.validated['tender_status'] not in ['active']:
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) tender status'.format(self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        if self.request.context.status == 'cancelled':
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) status'.format(self.request.context.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 self.request.validated['tender'].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 less or equal to awarded amount ({})'.format(award.value.amount))
                self.request.errors.status = 403
                return

        contract_dateSigned = self.request.context.dateSigned
        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' and 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.dateSigned != contract_dateSigned:
            if self.request.context.dateSigned < (get_now() - timedelta(days=1)):
                self.request.errors.add('body', 'data', 'dateSigned has to be within the period of 24 hours before the current date')
                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_tender_status(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 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.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)}
コード例 #31
0
 def patch(self):
     """Update of lot
     """
     if not self.validate_update_tender('update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         LOGGER.info('Updated tender lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #32
0
 def patch(self):
     """Tender Contract Document Update"""
     if not self.validate_contract_document('update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated tender contract document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #33
0
 def patch(self):
     """Tender Document Update"""
     if not self.validate_update_tender('update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #34
0
 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")}
コード例 #35
0
ファイル: bid.py プロジェクト: Vanuan/openprocurement.api
    def patch(self):
        """Update of proposal

        Example request to change bid proposal:

        .. sourcecode:: http

            PATCH /tenders/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.validated['tender_status'] != 'active.tendering':
            self.request.errors.add('body', 'data', 'Can\'t update bid in current tender status')
            self.request.errors.status = 403
            return
        apply_patch(self.request, src=self.request.context.serialize())
        return {'data': self.request.validated['bid'].serialize("view")}
コード例 #36
0
 def patch(self):
     """Post a cancellation resolution
     """
     tender = self.request.validated["tender"]
     if tender.status in ["complete", "cancelled", "unsuccessful"]:
         self.request.errors.add(
             "body", "data", "Can't update cancellation in current ({}) tender status".format(tender.status)
         )
         self.request.errors.status = 403
         return
     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")}
コード例 #37
0
 def patch(self):
     """Tender Award Document Update"""
     if self.request.validated['tender_status'] != 'active.qualification':
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender award document {}'.format(self.request.context.id), extra={'MESSAGE_ID': 'tender_award_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #38
0
 def patch(self):
     """Tender Cancellation Document Update"""
     if self.request.validated['tender_status'] in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender cancellation document {}'.format(self.request.context.id), extra={'MESSAGE_ID': 'tender_cancellation_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #39
0
 def patch(self):
     """Tender Complaint Document Update"""
     if self.request.validated['tender_status'] not in ['active.enquiries', 'active.tendering', 'active.auction', 'active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender complaint document {}'.format(self.request.context.id), extra={'MESSAGE_ID': 'tender_complaint_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #40
0
 def patch(self):
     """Update of lot
     """
     if not self.validate_update_tender('update'):
         return
     if self.request.authenticated_role == 'tender_owner':
         self.request.validated['tender'].invalidate_bids_data()
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info('Updated tender lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #41
0
 def patch(self):
     """Tender Cancellation Document Update"""
     if self.request.validated['tender_status'] in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_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 tender cancellation document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_cancellation_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #42
0
 def patch(self):
     """Update of lot
     """
     if not self.validate_update_tender('update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated tender lot {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #43
0
 def patch(self):
     """Post an Answer
     """
     tender = self.request.validated['tender']
     if tender.status != 'active.enquiries':
         self.request.errors.add('body', 'data', 'Can\'t update question in current ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         LOGGER.info('Updated tender question {}'.format(self.request.context.id), extra={'MESSAGE_ID': 'tender_question_patch'})
         return {'data': self.request.context.serialize(tender.status)}
コード例 #44
0
 def patch(self):
     """Tender Document Update"""
     if not self.validate_update_tender('update'):
         return
     if self.request.authenticated_role == 'tender_owner' and self.request.validated['tender_status'] == 'active.tendering':
         self.request.validated['tender'].invalidate_bids_data()
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated tender document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #45
0
 def collection_patch(self):
     """Set urls for access to auction.
     """
     if apply_patch(self.request, src=self.request.validated['tender_src']):
         self.LOGGER.info(
             'Updated auction urls',
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_auction_patch'}))
         return {
             'data':
             self.request.validated['tender'].serialize("auction_view")
         }
コード例 #46
0
 def patch(self):
     """Update of lot
     """
     tender = self.request.validated['tender']
     if tender.status not in ['active.enquiries']:
         self.request.errors.add('body', 'data', 'Can\'t update lot in current ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         LOGGER.info('Updated tender lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #47
0
ファイル: lot.py プロジェクト: digideskio/openprocurement.api
 def patch(self):
     """Update of lot
     """
     tender = self.request.validated['tender']
     if tender.status not in ['active.enquiries']:
         self.request.errors.add('body', 'data', 'Can\'t update lot in current ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info('Updated tender lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #48
0
    def patch(self):
        """Update of proposal

        Example request to change bid proposal:

        .. sourcecode:: http

            PATCH /tenders/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.validated['tender_status'] != 'active.tendering':
            self.request.errors.add(
                'body', 'data',
                'Can\'t update bid in current ({}) tender status'.format(
                    self.request.validated['tender_status']))
            self.request.errors.status = 403
            return
        value = self.request.validated['data'].get("value", {}).get("amount")
        if value and value != self.request.context.get("value",
                                                       {}).get("amount"):
            self.request.validated['data']['date'] = get_now().isoformat()
        if apply_patch(self.request, src=self.request.context.serialize()):
            LOGGER.info('Updated tender bid {}'.format(
                self.request.context.id),
                        extra={'MESSAGE_ID': 'tender_bid_patch'})
            return {'data': self.request.context.serialize("view")}
コード例 #49
0
 def patch(self):
     """Tender Document Update"""
     if self.request.authenticated_role != 'auction' and self.request.validated['tender_status'] != 'active.enquiries' or \
        self.request.authenticated_role == 'auction' and self.request.validated['tender_status'] not in ['active.auction', 'active.qualification']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #50
0
 def patch(self):
     """Tender Bid Document Update"""
     if self.request.validated['tender_status'] not in [
             'active.tendering', 'active.qualification'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if self.request.validated[
             'tender_status'] == 'active.qualification' and not [
                 i for i in self.request.validated['tender'].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[
             'tender_status'] != 'active.tendering' and 'confidentiality' in self.request.validated[
                 'data']:
         if self.context.confidentiality != self.request.validated['data'][
                 'confidentiality']:
             self.request.errors.add(
                 'body', 'data',
                 'Can\'t update document confidentiality in current ({}) tender status'
                 .format(self.request.validated['tender_status']))
             self.request.errors.status = 403
             return
     bid = getattr(self.context, "__parent__")
     if bid and bid.status in ['invalid', 'unsuccessful', 'deleted']:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document data for \'{}\' bid'.format(
                 bid.status))
         self.request.errors.status = 403
         return
     if self.request.validated['tender_status'] == 'active.tendering':
         self.request.validated['tender'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated tender bid document {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'tender_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #51
0
 def patch(self):
     """Tender Document Update"""
     if not self.validate_update_tender('update'):
         return
     if self.request.authenticated_role == 'tender_owner' and self.request.validated[
             'tender_status'] == 'active.tendering':
         self.request.validated['tender'].invalidate_bids_data()
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info(
             'Updated tender document {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #52
0
 def patch(self):
     """Tender Award Document Update"""
     if self.request.validated['tender_status'] != 'active.qualification':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender award document {}'.format(
             self.request.context.id),
                     extra={'MESSAGE_ID': 'tender_award_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #53
0
 def patch(self):
     """Post an Answer
     """
     if not self.validate_question('update'):
         return
     self.context.dateAnswered = get_now()
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated tender question {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_question_patch'}))
         return {
             'data':
             self.request.context.serialize(
                 self.request.validated['tender_status'])
         }
コード例 #54
0
 def patch(self):
     """Tender Document Update"""
     if self.request.authenticated_role != 'auction' and self.request.validated['tender_status'] != 'active.enquiries' or \
        self.request.authenticated_role == 'auction' and self.request.validated['tender_status'] not in ['active.auction', 'active.qualification']:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         LOGGER.info('Updated tender document {}'.format(
             self.request.context.id),
                     extra={'MESSAGE_ID': 'tender_document_patch'})
         return {'data': self.request.context.serialize("view")}
コード例 #55
0
 def patch(self):
     """Tender Bid Document Update"""
     if self.request.validated['tender_status'] not in [
             'active.tendering', 'active.qualification', 'active.awarded'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) tender status'.format(
                 self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     tender = self.request.validated['tender']
     if self.request.validated['tender_status'] == 'active.tendering' and (
             tender.tenderPeriod.startDate
             and get_now() < tender.tenderPeriod.startDate
             or get_now() > tender.tenderPeriod.endDate):
         self.request.errors.add(
             'body', 'data',
             'Document can be updated only during the tendering period: from ({}) to ({}).'
             .format(
                 tender.tenderPeriod.startDate
                 and tender.tenderPeriod.startDate.isoformat(),
                 tender.tenderPeriod.endDate.isoformat()))
         self.request.errors.status = 403
         return
     if self.request.validated['tender_status'] in ['active.qualification', 'active.awarded'] and \
             not [i for i in self.request.validated['tender'].awards if i.status in ['pending', 'active'] 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 or active state'
         )
         self.request.errors.status = 403
         return
     if self.request.validated['tender_status'] == 'active.tendering':
         self.request.validated['tender'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated tender bid document {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'tender_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #56
0
 def patch(self):
     """Tender Contract Document Update"""
     if self.request.validated['tender_status'] not in ['active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) tender status'.format(self.request.validated['tender_status']))
         self.request.errors.status = 403
         return
     tender = self.request.validated['tender']
     contract = self.request.validated['contract']
     if any([i.status != 'active' for i in tender.lots if i.id in [a.lotID for a in tender.awards if a.id == contract.awardID]]):
         self.request.errors.add('body', 'data', 'Can update document only in active lot status')
         self.request.errors.status = 403
         return
     if contract.status not in ['pending', 'active']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current contract 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 tender contract document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_contract_document_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #57
0
 def patch(self):
     """Update of lot
     """
     if not self.validate_update_tender('update'):
         return
     tender = self.request.validated['tender']
     lot = self.request.context
     if [
             cancellation for cancellation in tender.get('cancellations')
             if cancellation.get('relatedLot') == lot['id']
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update lot when it has \'pending\' cancellation.')
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated tender lot {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
コード例 #58
0
 def patch(self):
     """Post a complaint resolution
     """
     tender = self.request.validated['tender']
     if tender.status != 'active.tendering':
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) tender status'.format(tender.status))
         self.request.errors.status = 403
         return
     if self.context.status not in ['draft', 'claim', 'answered', 'pending', 'accepted', 'satisfied']:
         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', 'accepted'] 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 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):
             self.request.errors.add('body', 'data', 'Can submit claim not later than {0.days} days before tenderPeriod end'.format(CLAIM_SUBMIT_TIME))
             self.request.errors.status = 403
             return
         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() > calculate_business_date(tender.tenderPeriod.endDate, -COMPLAINT_SUBMIT_TIME):
             self.request.errors.add('body', 'data', 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME))
             self.request.errors.status = 403
             return
         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() > calculate_business_date(tender.tenderPeriod.endDate, -COMPLAINT_SUBMIT_TIME):
             self.request.errors.add('body', 'data', 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME))
             self.request.errors.status = 403
             return
         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 in ['claim', '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':
         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 == '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 == '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 == 'aboveThresholdReviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == 'invalid':
         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 == 'accepted' 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 == 'accepted' 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()
     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', 'accepted'] 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")}