def render_failure(self, failure: 'CaseError', **kwargs) -> http.HttpResponse: Logger.warning(__name__, str(failure)) if failure.failure in (ReservationErrors.missed_house, ReservationErrors.missed_room): raise http.Http404(failure.error) elif failure.failure == ReservationErrors.busy_room: return self.json_error(_('agenda:error:busy_room')) return http.HttpResponseServerError()
def parse_reservation_date_from_input( self, data: Dict[str, Any]) -> Union[http.HttpResponse, ReservationRequest]: roomtype_id = cf.get_int_or_none(data.get('room_type')) or 0 if roomtype_id <= 0: return self.json_error(_('agenda:room_type:error')) plan_id = cf.get_int_or_none(data.get('plan')) or 0 if plan_id <= 0: return self.json_error(_('agenda:plan:error')) period = cf.parse_period(data.get('period', '')) if period == Nothing: return self.json_error(_('agenda:period:error')) start_date, end_date = period.unwrap() guest_count = cf.get_int_or_none(data.get('guest_count')) or 0 if guest_count <= 0: return self.json_error(_('agenda:guest_count:error')) try: reservation = ReservationRequest( roomtype_id=roomtype_id, plan_id=plan_id, checkin=start_date, checkout=end_date, guests=guest_count, guest_name=data.get('guest_name', '').strip(), guest_surname=data.get('guest_surname', '').strip(), guest_email=data.get('guest_email', '').strip(), guest_phone=self.parse_phone(data), notes=data.get('notes', '').strip(), ) except ValidationError as err: Logger.warning(__name__, f"Error create a new Reservation Request: {err}") return http.HttpResponseServerError() return reservation
def render_failure(self, failure: 'CaseError', **kwargs) -> http.HttpResponse: Logger.warning(__name__, str(failure)) if failure.failure in (ReservationErrors.missed_house, ReservationErrors.missed_reservation): raise http.Http404(failure.error) return super().render_failure(failure)
def select_rate_plans(house: 'House', user: '******', prices_repo: PricesRepo) -> List[RatePlan]: try: return prices_repo.select_plans(house, user=user) except Exception as err: Logger.warning( __name__, f"Error select Rate Plans for House ID={house.id} : {err}") return []
def select_phone_codes(geo_repo: GeoRepo) -> List[Tuple[str, str]]: try: codes = geo_repo.get_phone_codes() except Exception as err: Logger.warning(__name__, f"Error select phone codes : {err}") return [] if not codes: return [] return list(set([(x, f"+{x}") for x in codes]))
def select_room_types(house: 'House', user: '******', roomtypes_repo: RoomTypesRepo) -> List[RoomType]: try: return roomtypes_repo.select(house, user=user) except Exception as err: Logger.warning( __name__, f"Error select Room Types for House ID={house.id} : {err}") return []
def load_reservation_request(self) -> Maybe[ReservationRequest]: try: return Some( ReservationRequest.parse_raw( self.request.session.get('NEWRES', '{}'))) except (ValidationError, ValueError) as err: Logger.warning( __name__, f"Error load reservation request from session: {err}") return Nothing
def render_failure(self, failure: Any, **kwargs) -> http.HttpResponse: Logger.warning(__name__, failure) if failure.failure in (ReservationErrors.missed_house, ReservationErrors.missed_reservation): raise http.Http404(failure.error) elif failure.failure == ReservationErrors.missed_rateplan: return self.json_error(_('agenda:plan:error')) elif failure.failure == ReservationErrors.wrong_period: return self.json_error(_('agenda:error:ota_update_period')) return http.HttpResponseServerError()
def render_failure(self, failure: 'CaseError', **kwargs) -> http.HttpResponse: Logger.warning(__name__, str(failure)) if failure.failure in ( ReservationErrors.missed_house, ReservationErrors.missed_roomtype, ReservationErrors.missed_rateplan, ReservationErrors.missed_rate, ): raise http.Http404(failure.error) return http.HttpResponseServerError()
def get(self, house_id: int, pk: str) -> Maybe[CachedReservation]: key = cache_keys.reservation(house_id, pk) data = self.get_store().get(key) if data is None or not data: return Nothing try: return Some(CachedReservation.parse_raw(data)) except ValidationError as err: Logger.warning(__name__, f"Error decode Cache Reservation [{key}] : {err}") return Nothing
def search(self, house_id: int) -> List[CachedReservation]: result = [] store = self.get_store() for key in store.keys(cache_keys.reservation(house_id, "*")): try: data = store.get(key).decode("utf8") result.append(CachedReservation.parse_raw(data)) except ValidationError as err: Logger.warning( __name__, f"Error decode Cache Reservation [{key}] : {err}") return result
def occupancies_json_view(request: http.HttpRequest, hid: int) -> http.HttpResponse: if not request.user.check_perms(Permissions.BOARD_READ, house_id=hid): # noqa return http.HttpResponseForbidden(_('common:error:access')) result = select_occupancies(hid, cf.get_date_or_none(request.GET.get('sd')), request.user) # noqa if is_successful(result): return json_response({'data': prepare_occupancies(result.unwrap().occupancies)}) failure = result.failure() Logger.warning(__name__, failure) if failure.failure == ReservationErrors.missed_house: raise http.Http404(f"Unknown House ID={hid}") return http.HttpResponseServerError()
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: self._changelog_repo.create( ctx.user, None, ctx.reservation, ChangelogActions.CREATE, house=ctx.house, message='Create a new Reservation', ) except Exception as err: Logger.warning(__name__, f"Error write changelog: {err}") return Success(ctx)
def _load_from_file(lang: str) -> Dict[str, str]: project_root = cf.get_config("PROJECT_ROOT") filename = project_root.joinpath("_i18n", f"{lang}.json") if not filename.exists(): Logger.warning(__name__, f"Translation file [{filename}] not exists") return {} try: with open(filename, "r") as f: return json.load(f) except Exception as err: Logger.warning(__name__, f"Error load translation from {filename} : {err}") return {}
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: self._changelog_repo.create_manual( ctx.user, ctx.reservation, ChangelogActions.CREATE, {}, house=ctx.house, message= f"Close Room [{ctx.room.name}] for {ctx.start_date.isoformat()}..{ctx.end_date.isoformat()}", ) except Exception as err: Logger.warning(__name__, f"Error write changelog: {err}") return Success(ctx)
def select_rooms(house: 'House', room_types: List[RoomType], rooms_repo: RoomsRepo) -> List[Tuple[int, str]]: result = [] try: _room_types = {x.id: x for x in room_types} data = rooms_repo.select(house_id=house.id) except Exception as err: Logger.warning(__name__, f"Error select Rooms for House ID={house.id} : {err}") return [] for room in data: name = f"{room.name} / {_room_types[room.roomtype_id].name}" if room.roomtype_id in _room_types else room.name result.append((room.id, name)) return sorted(result, key=lambda x: x[1])
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: self._changelog_repo.create_manual( ctx.user, ctx.reservation, ChangelogActions.UPDATE, {}, house=ctx.house, message= f"Update prices for Reservation {ctx.reservation.get_id_for_log()}", ) except Exception as err: Logger.warning(__name__, f"Error write changelog: {err}") 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 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 get_context_data(self, ctx: 'CalendarContext' = None, **kwargs: Any) -> Dict[str, Any]: context = super().get_context_data(**kwargs) context.update(ctx.asdict()) context['house'] = context['CURRENT_HOUSE'] = ctx.house context['structure'] = self.prepare_structure(ctx.room_types, ctx.rooms) context['close_reasons'] = RoomCloseReasons.choices() try: context['close_rooms'] = self.prepare_close_rooms( ctx.rooms, ctx.room_types) except Exception as err: Logger.warning( __name__, f"Error select Rooms for House ID={ctx.house.id} : {err}") return context
def update_reservation_in_odoo(self, hid: int, pk: int, user_id: int = None) -> None: result = UpdateReservationInOdoo().execute(hid, pk, user_id=user_id) if is_successful(result): auto_make_invoice.delay(pk) return failure = result.failure() if failure.failure == ReservationErrors.room_close_reservation: # It's normal case but use error just for breaking flow return Logger.warning(__name__, failure) nf.notify_warning( f"Error update Reservation ID={pk} in Odoo\n{failure.short_info()}") if failure.failure == ReservationErrors.error: raise self.retry(exc=failure.exc)
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: self._changelog_repo.create_manual( ctx.user, ctx.reservation, ChangelogActions.DELETE, changes={ 'status': (ReservationStatuses.CLOSE.value, ReservationStatuses.CANCEL.value) }, house=ctx.house, message= (f"Open room for {ctx.reservation.checkin.isoformat()}..{ctx.reservation.checkout.isoformat()}" ), ) except Exception as err: Logger.warning(__name__, f"Error write changelog: {err}") return Success(ctx)
def select_policies(house: 'House', rate_plans: List['RatePlan'], policies_repo: PoliciesRepo) -> Dict[int, str]: if not rate_plans: return {} try: policies = {x.id: x.name for x in policies_repo.select(house.id)} except Exception as err: Logger.warning( __name__, f"Error select Cancellation Policies for House ID={house.id} : {err}" ) return {} if not policies: return {} return { x.id: policies[x.policy_id] for x in rate_plans if x.policy_id in policies }
def write_changelog(self, ctx: Context) -> ResultE[Context]: """Register user action""" if ctx.source.status == ctx.reservation.status: # Reservation was canceled before return Success(ctx) try: self._changelog_repo.create( ctx.user, ctx.source, ctx.reservation, ChangelogActions.DELETE, house=ctx.house, message= f"Cancel Reservation {ctx.reservation.get_id_for_log()}", ) except Exception as err: Logger.warning(__name__, f"Error write changelog : {err}") return Success(ctx)
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: changes = {} if ctx.source.checkin != ctx.reservation.checkin: changes['checkin'] = ( ctx.source.checkin.strftime('%d/%m/%Y'), ctx.reservation.checkin.strftime('%d/%m/%Y'), ) if ctx.source.checkout != ctx.reservation.checkout: changes['checkout'] = ( ctx.source.checkout.strftime('%d/%m/%Y'), ctx.reservation.checkout.strftime('%d/%m/%Y'), ) if ctx.source.close_reason != ctx.reservation.close_reason: changes['close_reason'] = ( ctx.source.close_reason.value if ctx.source.close_reason is not None else None, ctx.reservation.close_reason.value if ctx.reservation.close_reason is not None else None, ) try: if ctx.source.rooms[0].notes_info != ctx.reservation.rooms[ 0].notes_info: changes['notes'] = (ctx.source.rooms[0].notes_info, ctx.reservation.rooms[0].notes_info) except IndexError: pass self._changelog_repo.create_manual( ctx.user, ctx.reservation, ChangelogActions.UPDATE, changes=changes, house=ctx.house, message= (f"Update Room [{ctx.room.name}] closing " f"for {ctx.start_date.isoformat()}..{ctx.end_date.isoformat()}" ), ) except Exception as err: Logger.warning(__name__, f"Error write changelog: {err}") return Success(ctx)
def calculate_occupancy( self, hid: int = None, rid: int = None, start_date: Union[str, datetime.date] = None, end_date: Union[str, datetime.date] = None, ) -> None: if start_date is not None and not isinstance(start_date, datetime.date): start_date = cf.get_date_or_none(start_date) if end_date is not None and not isinstance(end_date, datetime.date): end_date = cf.get_date_or_none(end_date) result = CalculateOccupancy().execute(house_id=hid, roomtype_id=rid, start_date=start_date, end_date=end_date) if is_successful(result): return failure = result.failure() Logger.warning(__name__, failure) nf.notify_warning(f"Error recalculate occupancy\n{failure.short_info()}") raise self.retry(exc=failure.exc)
def write_changelog(self, ctx: Context) -> ResultE[Context]: try: destination = '' if ctx.room_type is not None: destination = ctx.room_type.name elif ctx.room is not None: destination = ctx.room.name self._changelog_repo.create_manual( ctx.user, ctx.reservation, ChangelogActions.UPDATE, {}, house=ctx.house, message= (f"Move Reservation {ctx.reservation.get_id()} " f"[{ctx.start_date.isoformat()}..{ctx.end_date.isoformat()}] to {destination}" ), ) except Exception as err: Logger.warning(__name__, f"Error write changelog : {err}") return Success(ctx)
def update_reservations( self, hid: int = None, pk: int = None, start_date: Union[str, datetime.date] = None, end_date: Union[str, datetime.date] = None, ) -> None: if start_date is not None and not isinstance(start_date, datetime.date): start_date = cf.get_date_or_none(start_date) if end_date is not None and not isinstance(end_date, datetime.date): end_date = cf.get_date_or_none(end_date) result = UpdateReservationCache().execute(house_id=hid, start_date=start_date, end_date=end_date, pk=pk) if is_successful(result): return failure = result.failure() Logger.warning(__name__, failure) nf.notify_warning( f"Error update reservation cache\n{failure.short_info()}") raise self.retry(exc=failure.exc)
def _send_bot_message(url: str, chat_id: str, message: str, disable_notification: bool = False) -> None: """Send message via given Telegram BOT url""" if url.strip() == "": raise AssertionError("Empty Telegram BOT url") if chat_id.strip() == "": raise AssertionError("Empty Chat/User ID") if message.strip() == "": return chunks = _split_message(message) for chunk in chunks: data = { "chat_id": chat_id, "text": chunk, "disable_notification": disable_notification, "disable_web_page_preview": 1, } if len(chunk) < 200: resp = requests.get(url, params=data) else: resp = requests.post(url, data) if resp.status_code != 200: if _mute_telegram_error(resp.content): # Don't send next chunks return Logger.warning( __name__, f"TELEGRAM (CHAT:{chat_id}): [{resp.status_code}] {resp.content!r}" ) continue try: resp.json() except ValueError as err: Logger.warning(__name__, f"TELEGRAM (CHAT:{chat_id}): {err}")
def render_failure(self, failure: 'CaseError', **kwargs) -> http.HttpResponse: Logger.warning(__name__, str(failure)) if failure.failure == CalendarErrors.missed_house: raise Http404(failure.error) return RenderServerError(request=self.request).do()