Ejemplo n.º 1
0
 async def create_offer_for_cleaning(self, *,
                                     new_offer: OfferCreate) -> OfferInDB:
     created_offer = await self.db.fetch_one(
         query=CREATE_OFFER_FOR_CLEANING_QUERY,
         values={
             **new_offer.dict(), "status": "pending"
         })
     return OfferInDB(**created_offer)
Ejemplo n.º 2
0
 async def get_offer_for_cleaning_from_user(self, *, cleaning: CleaningInDB, user: UserInDB) -> OfferInDB:
     offer_record = await self.db.fetch_one(
         query=GET_OFFER_FOR_CLEANING_FROM_USER_QUERY,
         values={"cleaning_id": cleaning.id, "user_id": user.id},
     )
     if not offer_record:
         return None
     return OfferInDB(**offer_record)
Ejemplo n.º 3
0
 async def populate_offer(self, *, offer: OfferInDB) -> OfferPublic:
     """
     Queries the user linked to the offer and populates the offer with it.
     """
     return OfferPublic(
         **offer.dict(),
         user=await self.users_repo.get_user_by_id(user_id=offer.user_id),
         # could populate cleaning here as well if needed
     )
Ejemplo n.º 4
0
 async def list_offers_for_cleaning(
     self, *, cleaning: CleaningInDB, populate: bool = True
 ) -> List[Union[OfferInDB, OfferPublic]]:
     offer_records = await self.db.fetch_all(
         query=LIST_OFFERS_FOR_CLEANING_QUERY, values={"cleaning_id": cleaning.id}
     )
     offers = [OfferInDB(**o) for o in offer_records]
     if populate:
         return [await self.populate_offer(offer=offer) for offer in offers]
     return offers
Ejemplo n.º 5
0
 async def cancel_offer(self, *, offer: OfferInDB) -> OfferInDB:
     async with self.db.transaction():
         cancelled_offer = await self.db.fetch_one(
             query=CANCEL_OFFER_QUERY,  # cancel current offer
             values={"cleaning_id": offer.cleaning_id, "user_id": offer.user_id},
         )
         await self.db.execute(
             query=SET_ALL_OTHER_OFFERS_AS_PENDING_QUERY,  # set all other offers to pending again
             values={"cleaning_id": offer.cleaning_id, "user_id": offer.user_id},
         )
         return OfferInDB(**cancelled_offer)
Ejemplo n.º 6
0
 async def create_offer_for_cleaning(self, *,
                                     new_offer: OfferCreate) -> OfferInDB:
     try:
         created_offer = await self.db.fetch_one(
             query=CREATE_OFFER_FOR_CLEANING_QUERY,
             values={
                 **new_offer.dict(), "status": "pending"
             })
         return OfferInDB(**created_offer)
     except UniqueViolationError:
         raise HTTPException(
             status_code=status.HTTP_400_BAD_REQUEST,
             detail=
             "Users aren't allowed create more than one offer for a cleaning job.",
         )
Ejemplo n.º 7
0
    async def create_offer_for_cleaning(self, *, new_offer: OfferCreate) -> OfferInDB:
        try:
            created_offer = await self.db.fetch_one(
                query=CREATE_OFFER_FOR_CLEANING_QUERY, values={**new_offer.dict(), "status": "pending"}
            )
            return OfferInDB(**created_offer)

        # this looks very familiar to the 403 unauthorized request we've refactored all
        # over the place into its own dependency. Catching a UniqueViolationError as a
        # way to prevent duplicate entries is another permissions issue. When we see
        # this, our thinking should go directly to dependencies.
        except UniqueViolationError:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Users aren't allowed create more than one offer for a cleaning job.",
            )
Ejemplo n.º 8
0
 async def accept_offer(self, *, offer: OfferInDB) -> OfferInDB:
     """
     Manages a transaction through an async context block.
     Transaction: all-or-nothing operation. The intermediate states between the steps
     are not visible to other concurrent transactions, and if some failure occurs,
     then none of the steps affect the database at all.
     """
     async with self.db.transaction():
         accepted_offer = await self.db.fetch_one(
             query=ACCEPT_OFFER_QUERY,  # accept current offer
             values={"cleaning_id": offer.cleaning_id, "user_id": offer.user_id},
         )
         await self.db.execute(
             query=REJECT_ALL_OTHER_OFFERS_QUERY,  # reject all other offers
             values={"cleaning_id": offer.cleaning_id, "user_id": offer.user_id},
         )
         return OfferInDB(**accepted_offer)
Ejemplo n.º 9
0
 async def accept_offer(self, *, offer: OfferInDB) -> OfferInDB:
     async with self.db.transaction():
         accepted_offer = await self.db.fetch_one(
             query=ACCEPT_OFFER_QUERY,  # accept current offer
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         await self.db.execute(
             query=REJECT_ALL_OTHER_OFFERS_QUERY,  # reject all other offers
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         return OfferInDB(**accepted_offer)
Ejemplo n.º 10
0
 async def cancel_offer(self, *, offer: OfferInDB,
                        offer_update: OfferUpdate) -> OfferInDB:
     async with self.db.transaction():
         cancelled_offer = await self.db.fetch_one(
             query=CANCEL_OFFER_QUERY,
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         await self.db.execute(
             query=SET_ALL_OTHER_OFFERS_AS_PENDING_QUERY,
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         return OfferInDB(**cancelled_offer)
Ejemplo n.º 11
0
 async def accept_offer(self, *, offer: OfferInDB,
                        offer_update: OfferUpdate) -> OfferInDB:
     async with self.db.transaction(
     ):  # this help bundle the multiple db operations to one. Execute all or no operation.
         accepted_offer = await self.db.fetch_one(
             query=ACCEPT_OFFER_QUERY,
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         await self.db.execute(
             query=REJECT_ALL_OTHER_OFFERS_QUERY,
             values={
                 "cleaning_id": offer.cleaning_id,
                 "user_id": offer.user_id
             },
         )
         return OfferInDB(**accepted_offer)
Ejemplo n.º 12
0
 async def list_offers_for_cleaning(
         self, *, cleaning: CleaningInDB) -> List[OfferInDB]:
     offers = await self.db.fetch_all(query=LIST_OFFERS_FOR_CLEANING_QUERY,
                                      values={"cleaning_id": cleaning.id})
     return [OfferInDB(**o) for o in offers]
Ejemplo n.º 13
0
 async def populate_offer(self, *, offer: OfferInDB) -> OfferPublic:
     return OfferPublic(
         **offer.dict(),
         user=await self.users_repo.get_user_by_id(user_id=offer.user_id),
         # could populate cleaning here as well if needed
     )