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()
Exemple #2
0
 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)
Exemple #4
0
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 []
Exemple #5
0
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]))
Exemple #6
0
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 []
Exemple #7
0
 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()
Exemple #9
0
 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()
Exemple #10
0
 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
Exemple #11
0
 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)
Exemple #14
0
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)
Exemple #16
0
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)
Exemple #19
0
 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
Exemple #21
0
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)
Exemple #23
0
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
    }
Exemple #24
0
 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)
Exemple #25
0
 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)
Exemple #26
0
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)
Exemple #27
0
 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)
Exemple #28
0
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)
Exemple #29
0
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()