def select_room( self, ctx: dataclasses.dataclass) -> ResultE[dataclasses.dataclass]: pk = cf.get_int_or_none(ctx.room_id) or 0 if pk <= 0: return self._error('Missed Room ID', ctx, self._case_errors.missed_room) try: data = self._rooms_repo.get(pk) except Exception as err: return self._error( f"Error select Room ID={pk} in House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err) if data == Nothing: return self._error( f"Unknown Room ID={pk} in House ID={ctx.house.id}", ctx, self._case_errors.missed_room) ctx.room = data.unwrap() if ctx.room.house_id != ctx.house.id: return self._error( f"Unknown Room ID={pk} in House ID={ctx.house.id}", ctx, self._case_errors.missed_room) return Success(ctx)
def remove_canceled_reservations(self, ctx: Context) -> ResultE[Context]: if not ctx.reservations: return Success(ctx) for reservation in ctx.reservations: if reservation.status != ReservationStatuses.CANCEL: continue try: self._cache_repo.delete(ctx.house.id, reservation.id) except Exception as err: return self._error( f"Error delete canceled Reservation ID={reservation.id} from Cache", ctx, self._case_errors.error, exc=err, ) return Success(ctx)
def cancel_quotation(self, ctx: Context) -> ResultE[Context]: """Cancel Quotation in Odoo""" if ctx.reservation.quotation_id is None or ctx.reservation.quotation_id <= 0: # Reservation wasn't registered in Odoo return Success(ctx) try: self.get_rpc_api(ctx).cancel_quotation( ctx.reservation.quotation_id) except Exception as err: return self._error( f"Error cancel Quotation ID={ctx.reservation.quotation_id} for Reservation ID={ctx.reservation.id}", ctx, self._case_errors.error, exc=err, ) return Success(ctx)
def execute( self, house_id: int, pk: int, room_id: int, plan_id: int, user: '******', prices: Dict[datetime.date, Dict[str, Any]] = None, ) -> ResultE['Reservation']: ctx = Context(house_id=house_id, pk=pk, room_id=room_id, user=user, plan_id=plan_id, prices=prices) return flow( ctx, self.select_house, bind_result(self.select_reservation), bind_result(self.check_reservation), bind_result(self.select_reservation_room), bind_result(self.is_allow_update_period), bind_result(self.select_rate_plan), bind_result(self.select_cancellation_policy), bind_result(self.select_room_types), bind_result(self.select_rooms), bind_result(self.make_reservation_from_data), bind_result(self.save_reservation), bind_result(self.write_changelog), bind_result(lambda x: Success(x.reservation)), )
def run(target_agents: Set[Agent], enemy_agents: Set[Agent] = set()): agent_key_sources = ( try_to_submit_source(agent).map(lambda sources: (agent.key, sources)) for agent in chain(target_agents, enemy_agents)) source_map = (Fold.loop( agent_key_sources, Success([]), lambda key_source: lambda acc: acc + [key_source], ).map(lambda key_sources: dict(key_sources)).unwrap()) result_futures = {} with ProcessPoolExecutor() as executor: for lh, rh in product(target_agents, chain(target_agents, enemy_agents)): if lh == rh: continue lh, rh = _swap_agents_if_need(lh, rh) result_key = _get_result_key(lh, rh) lh_source = source_map[lh.key] rh_source = source_map[rh.key] result_futures[result_key] = executor.submit( _run_inner, lh_source, rh_source) return {k: f.result() for k, f in result_futures.items()}
def execute( self, pk: str, reservation_id: int, house_id: int, roomtype_id: int = None, room_id: int = None, user: '******' = None, ) -> ResultE[None]: ctx = Context( pk=pk, reservation_id=reservation_id, house_id=house_id, roomtype_id=roomtype_id, room_id=room_id, user=user, ) return flow( ctx, self.select_house, bind_result(self.select_reservation_from_cache), bind_result(self.select_reservation_from_db), bind_result(self.select_room_type), bind_result(self.select_room), bind_result(self.update_reservation), bind_result(self.save), bind_result(self.write_changelog), bind_result(lambda x: Success(None)), )
def check_columns(self, df: DataFrame, columns: List[str]) -> Result[DataFrame, InvalidJob]: keys = df.dtypes.keys() diff = set(columns).difference(set(df.dtypes.keys())) if len(diff) == 0: return Success(df) else: return Failure(InvalidJob(f"Filter columns {', '.join(diff)} not a subset of {', '.join(keys)}"))
def make_reservation_from_data(ctx: Context) -> ResultE[Context]: rooms = [] for room in ctx.source.rooms: source_prices = {x.day: x for x in room.day_prices} prices = [] for day in cf.get_days_for_period(ctx.start_date, ctx.end_date, exclude=True): if day in source_prices: prices.append( attr.evolve(source_prices[day], roomtype_id=ctx.room.roomtype_id, room_id=ctx.room.id)) else: prices.append( ReservationDay( id=None, reservation_room_id=room.id, day=day, roomtype_id=ctx.room.roomtype_id, room_id=ctx.room.id, )) rooms.append( attr.evolve(room, checkin=ctx.start_date, checkout=ctx.end_date, notes_info=ctx.notes, day_prices=prices)) ctx.reservation = attr.evolve(ctx.source, checkin=ctx.start_date, checkout=ctx.end_date, close_reason=ctx.reason, rooms=rooms) return Success(ctx)
def execute( self, house_id: int, room_id: int, start_date: datetime.date, end_date: datetime.date, reason: RoomCloseReasons, user: '******', notes: str = '', ) -> ResultE[Reservation]: ctx = Context( house_id=house_id, room_id=room_id, start_date=start_date, end_date=end_date, reason=reason, user=user, notes=notes, ) return flow( ctx, self.select_house, bind_result(self.select_room), bind_result(self.check_room_is_free), bind_result(self.make_reservation_from_date), bind_result(self.save_reservation), bind_result(self.accept_reservation), bind_result(self.write_changelog), bind_result(lambda x: Success(x.reservation)), )
def check_reservation(self, ctx: Context) -> ResultE[Context]: if ctx.reservation.house_id != ctx.house.id: return self._error( f"Reservation ID={ctx.reservation.id} has House ID={ctx.reservation.house_id} " f"but needs to be House ID={ctx.house.id}", ctx, self._case_errors.missed_reservation, ) if ctx.reservation.status == ReservationStatuses.CLOSE: return self._error( f"Reservation ID={ctx.reservation.id} is Room-Close and can't be verified", ctx, self._case_errors.missed_reservation, ) if not ctx.reservation.is_ota(): return self._error( f"Reservation ID={ctx.reservation.id} is not from OTA and can't be verified", ctx, self._case_errors.missed_reservation, ) if ctx.reservation.status == ReservationStatuses.CANCEL: return self._error( f"Reservation ID={ctx.reservation.id} is canceled and not need to be verified", ctx, self._case_errors.missed_reservation, ) return Success(ctx)
def write_changelog(self, ctx: Context) -> ResultE[Context]: if ctx.source.is_verified: # Reservation was verified before return Success(ctx) try: self._changelog_repo.create( ctx.user, ctx.source, ctx.reservation, ChangelogActions.UPDATE, house=ctx.house, message= f"Accept changes in Reservation {ctx.reservation.get_id()}") except Exception as err: Logger.warning(__name__, f"Error write changelog : {err}") return Success(ctx)
def test_should_return_failure_when_save_stream_fails( create_new_stream_from_stream_use_case: CreateNewStreamFromStreamUseCase, create_new_stream_from_stream: Mock, save_stream: Mock, ) -> None: command = CreateNewStreamCommand( project_id=uuid4(), stream_name="TEST_STREAM_FAILURE", fields=[ CreateNewStreamCommand.StreamField(name="field_test", type="STRING"), CreateNewStreamCommand.StreamField(name="another_field_test", type="STRING"), ], source_name="TEST_STREAM", source_type=SourceType.STREAM, ) failure = Failure(FailureDetails(reason="TEST_SAVE_STREAM_FAILS")) create_new_stream_from_stream.return_value = Success(command) save_stream.return_value = failure actual = create_new_stream_from_stream_use_case(command) create_new_stream_from_stream.assert_called_with(command) save_stream.assert_called_with(command) assert isinstance(actual, Result.failure_type) assert isinstance(actual.failure(), BusinessFailureDetails) assert "NON_BUSINESS_RULE_CAUSE" == actual.failure().reason assert failure.failure() == actual.failure().failure_due
def check_last_minute_discounts(self, ctx: Context) -> ResultE[Context]: if not ctx.discounts or ctx.rate is None or not ctx.prices: return Success(ctx) discounts = ctx.discounts.get(DiscountTypes.LAST_MINUTE, []) if not discounts: return Success(ctx) try: ctx.prices = {x: self.apply_last_minute_discount(discounts, x, y) for x, y in ctx.prices.items()} except Exception as err: return self._error( f"Error apply Last Minute Discounts for Room Type ID={ctx.room_type.id} in House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err, ) return Success(ctx)
def _try_to_get_response(self, expected_response_type, MAX_ATTEMTS=20): current_attempt = 0 received_bytes = [] while current_attempt < MAX_ATTEMTS: if self.serial_handler.in_waiting > 0: received_byte = self.serial_handler.read() received_bytes.append(received_byte) parsing_result = self.parser.parse_byte(received_byte) #print(parsing_result.get_state()) if parsing_result.is_parsed(): data_string = ' | '.join( [data.hex() for data in received_bytes]) self.logger.debug(f'Received bytes: {data_string}') message = parsing_result.get_message() if (message.get_message_type() == expected_response_type): #print(message.get_bytes()) return Success(message) else: return Failure( f'Wrong message type returned. Expected {expected_response_type.get_label()} but received {message.get_message_type().get_label()}' ) else: time.sleep(0.2) current_attempt += 1 return Failure("Failed all attempts to receive the response message")
def select_rate(self, ctx: Context) -> ResultE[Context]: pk = cf.get_int_or_none(ctx.request.rate_id) or 0 if pk <= 0: return self._error('Missed Rate ID', ctx, self._case_errors.missed_rate) try: rates = self._prices_repo.select_rates(ctx.house, room_type=ctx.room_type, plan_id=ctx.rate_plan.id, user=ctx.user) except Exception as err: return self._error( f"Error select Rates for Room Type ID={ctx.room_type.id} in House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err, ) rates = [x for x in rates if x.id == pk] if not rates: return self._error( f"Unknown Rate ID={pk} for Room Type ID={ctx.room_type.id} in House ID={ctx.house.id}", ctx, self._case_errors.missed_rate, ) ctx.rate = rates[0] return Success(ctx)
def make_result(ctx: Context) -> ResultE[ReservationUpdateContext]: return Success( ReservationUpdateContext( reservation=ctx.reservation, start_date=min(ctx.source.checkin, ctx.reservation.checkin), end_date=max(ctx.source.checkout, ctx.reservation.checkout), ))
def list_tables( self, database_name: str, response: Response ) -> Tuple[Result[TableList, InvalidTables], Response]: try: result = self.client().get_tables(DatabaseName=database_name) except ClientError as e: result = e.response response.add_response(result) error, status, message = self.parse_response(result) if error == "EntityNotFoundException": final = Failure( InvalidTables([], f"Database {database_name} not found")) response.set_status(404) return final, response elif 200 <= status < 300: valid: List[Table] valid, invalid = self.parse_table_list_data( result, Path(database_name, "glue"), database_name) if len(valid) > 0: response.set_status(status) return Success(TableList(valid)), response else: return Failure(InvalidTables( [], "No Valid tables found")), response else: response.set_status(status) return Failure(InvalidTables(message)), response
def cancel_opportunity(self, ctx: Context) -> ResultE[Context]: """Cancel Opportunity (mark lost) in Odoo""" if ctx.reservation.opportunity_id is None or ctx.reservation.opportunity_id <= 0: # Reservation wasn't registered in Odoo return Success(ctx) try: self.get_rpc_api(ctx).cancel_opportunity( ctx.reservation.opportunity_id, CrmLostReasons.EXPENSIVE) except Exception as err: return self._error( f"Error cancel Opportunity ID={ctx.reservation.opportunity_id} " f"for Reservation ID={ctx.reservation.id}", ctx, self._case_errors.error, exc=err, ) return Success(ctx)
def make_reservation_from_data(ctx: Context) -> ResultE[Context]: if ctx.source.guest_contact_id == 0 or ctx.contact_id != ctx.source.guest_contact_id: ctx.reservation = ctx.source return Success(ctx) if ctx.attribute == 'name': value = (ctx.value or '').strip().split(' ', maxsplit=1) ctx.reservation = attr.evolve( ctx.source, guest_name=value[0].strip(), guest_surname=value[1].strip() if len(value) > 1 else '' ) elif ctx.attribute == 'email': ctx.reservation = attr.evolve(ctx.source, guest_email=ctx.value or '') elif ctx.attribute == 'phone': ctx.reservation = attr.evolve(ctx.source, guest_phone=ctx.value or '') else: ctx.reservation = ctx.source return Success(ctx)
def check_los_discounts(self, ctx: Context) -> ResultE[Context]: if not ctx.discounts or ctx.rate is None or not ctx.prices: return Success(ctx) discounts = ctx.discounts.get(DiscountTypes.LOS, []) if not discounts: return Success(ctx) try: nights = (ctx.end_date - ctx.start_date).days ctx.prices = {x: self.apply_los_discount(discounts, x, y, nights) for x, y in ctx.prices.items()} except Exception as err: return self._error( f"Error apply Last Minute Discounts for Room Type ID={ctx.room_type.id} in House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err, ) return Success(ctx)
def select_cancellation_policy(self, ctx: Context) -> ResultE[Context]: if ctx.rate_plan.policy_id is None or ctx.rate_plan.policy_id <= 0: return Success(ctx) try: data = self._policies_repo.get(ctx.house.id, ctx.rate_plan.policy_id, detailed=True) except Exception as err: return self._error( f"Error select Cancellation Policy ID={ctx.rate_plan.policy_id} for House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err, ) if data != Nothing: ctx.rate_plan.policy = data.unwrap() return Success(ctx)
def __call__(self, project_id: UUID) -> Result[Maybe[Project], FailureDetails]: project = ProjectModel.query.filter( ProjectModel.project_id == project_id).first() maybe_project: Maybe[Project] = Maybe.from_value(project).map( lambda _project: _project.to_entity() # type: ignore ) return Success(maybe_project)
def maybe_to_result( maybe_container: Maybe[_ValueType], ) -> Result[_ValueType, None]: """Converts ``Maybe`` container to ``Result`` container.""" inner_value = maybe_container.value_or(None) if inner_value is not None: return Success(inner_value) return Failure(inner_value)
def get(self, object_id, survey_id): astro_obj = self._get_object_by_id(object_id, survey_id) if is_successful(astro_obj): detections = astro_obj.unwrap().detections return Success(detections) else: return astro_obj
def write_changelog(self, ctx: Context) -> ResultE[Context]: """Register changes made by User""" if ctx.source.status == ctx.reservation.status: # It wasn't HOLD reservation return Success(ctx) try: self._changelog_repo.create( ctx.user, ctx.source, ctx.reservation, ChangelogActions.UPDATE, house=ctx.house, message='User accept HOLD reservation', ) except Exception as err: Logger.warning(__name__, f"Error register changelog: {err}") return Success(ctx)
def __verify_response(self, response: JsonResponse) -> Result[TopicSchema, Any]: if ( isinstance(response, dict) and not response.get("message") == "Subject not found." ): schema = orjson.loads(response["schema"]) return Success(TopicSchema(**schema)) return Failure(response)
def __call__(self, stream_id: UUID) -> Result[Maybe[Stream], FailureDetails]: stream = StreamModel.query.filter( StreamModel.stream_id == stream_id).first() maybe_stream: Maybe[Stream] = Maybe.from_value(stream).map( lambda _stream: _stream.to_entity() # type: ignore ) return Success(maybe_stream)
async def async_bind_io( function: Callable[[_ValueType], IO[_NewValueType]], inner_value: Awaitable[Result[_ValueType, _ErrorType]], ) -> Result[_NewValueType, _ErrorType]: """Async binds a container returning ``IO`` over a value.""" container = await inner_value if isinstance(container, Result.success_type): return Success(function(container.unwrap())._inner_value) return container # type: ignore
async def async_fix( function: Callable[[_ErrorType], _NewValueType], inner_value: Awaitable[Result[_ValueType, _ErrorType]], ) -> Result[_NewValueType, _ErrorType]: """Async fixes a function over a value.""" container = await inner_value if isinstance(container, Result.success_type): return container return Success(function(container.failure()))
def test_unify_and_bind(): """Ensures that left identity works for Success container.""" def factory(inner_value: int) -> Result[int, str]: return Success(inner_value * 2) bound: Result[int, str] = Success(5) assert bound.unify(factory) == bound.bind(factory) assert bound.bind(factory) == bound.unify(factory)