Пример #1
0
    def get(self, request: http.HttpRequest, *args: Any,
            **kwargs: Any) -> http.HttpResponse:
        self._plan_id = cf.get_int_or_none(
            request.GET.get('plan')) or 0  # noqa
        if self._plan_id <= 0:
            return self.json_error(_('agenda:plan:error'))

        data = self.load_reservation_request()
        if data == Nothing:
            return http.HttpResponseServerError()
        self._reservation = data.unwrap()

        self._rate_id = cf.get_int_or_none(request.GET.get('rate'))  # noqa
        if self._plan_id == self._reservation.plan_id and self._rate_id is None:
            self._rate_id = self._reservation.rate_id

        return self.process_usecase(
            CalculateNewReservation,
            self.kwargs['hid'],
            self._reservation.roomtype_id,
            self._plan_id,
            self._reservation.checkin,
            self._reservation.checkout,
            self._reservation.guests,
            request.user,
            rate_id=self._rate_id,
        )
Пример #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
Пример #3
0
    def post(self, request: http.HttpRequest, *args: Any,
             **kwargs: Any) -> http.HttpResponse:
        data = request.POST.dict()  # noqa

        value = self.load_reservation_request()
        if value == Nothing:
            return http.HttpResponseServerError()
        self._reservation = value.unwrap()

        self._reservation.plan_id = cf.get_int_or_none(data.get('plan')) or 0
        if self._reservation.plan_id <= 0:
            return self.json_error(_('agenda:plan:error'))

        self._reservation.rate_id = cf.get_int_or_none(data.get('rate'))
        if self._reservation.rate_id <= 0:
            return self.json_error(_('agenda:rate:error'))

        try:
            self.assign_prices_to_reservation(
                request.POST.getlist('prices'))  # noqa
        except (IndexError, AssertionError):
            return self.json_error(_('agenda:price:error'))

        return self.process_usecase(CreateReservation, self.kwargs['hid'],
                                    self._reservation, request.user)
Пример #4
0
 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 post(self, request: http.HttpRequest, *args: Any,
          **kwargs: Any) -> http.HttpResponse:
     pk = cf.get_int_or_none(self.kwargs.get('pk')) or 0
     if pk <= 0:
         raise http.Http404('Wrong or missed Reservation ID')
     return self.process_usecase(AcceptHoldReservation,
                                 self.kwargs.get('hid'), pk, request.user)
    def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse:
        price_ids = [cf.get_int_or_none(x) for x in request.POST.getlist('price_verify')]  # noqa
        price_ids = [x for x in price_ids if x is not None and x > 0]

        return self.process_usecase(
            AcceptReservationChanges, self.kwargs['hid'], self.kwargs['pk'], request.user, price_ids=price_ids
        )
 def select_rate_by_id(ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.rate_id) or 0
     if pk <= 0 or not ctx.rates:
         return Success(ctx)
     _rates = {x.id: x for x in ctx.rates}
     ctx.rate = _rates.get(pk)
     return Success(ctx)
Пример #8
0
 def execute(
     self,
     pk: str,
     house_id: int,
     room_id: int,
     start_date: datetime.date,
     end_date: datetime.date,
     reason: RoomCloseReasons,
     user: '******',
     notes: str = '',
 ) -> ResultE[ReservationUpdateContext]:
     pk = cf.get_int_or_none((pk or '').split('-')[0]) or 0
     ctx = Context(
         pk=pk,
         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.select_reservation),
         bind_result(self.check_room_is_free),
         bind_result(self.make_reservation_from_data),
         bind_result(self.save_reservation),
         bind_result(self.accept_reservation),
         bind_result(self.write_changelog),
         bind_result(self.make_result),
     )
 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 execute(self, house_id: int, pk: int, contact_id: int, attribute: str, value: Any) -> ResultE['Reservation']:
     ctx = Context(
         house_id=house_id,
         pk=pk,
         contact_id=cf.get_int_or_none(contact_id) or 0,
         attribute=(attribute or '').strip().lower(),
         value=value,
     )
     if ctx.contact_id <= 0:
         return self._error(
             f"Missed Contact ID for update Guest information in Reservation ID={ctx.pk}",
             ctx,
             self._case_errors.error,
         )
     if ctx.attribute == '':
         return self._error(
             f"Missed attribute for update Guest information in Reservation ID={ctx.pk}",
             ctx,
             self._case_errors.error,
         )
     if ctx.attribute not in ('name', 'email', 'phone'):
         return self._error(
             f"Unsupported attribute [{ctx.attribute}] for update Guest information in Reservation ID={ctx.pk}",
             ctx,
             self._case_errors.error,
         )
     return flow(
         ctx,
         self.select_house,
         bind_result(self.select_reservation),
         bind_result(self.check_reservation),
         bind_result(self.make_reservation_from_data),
         bind_result(self.save_reservation),
         bind_result(lambda x: Success(x.reservation)),
     )
Пример #11
0
    def channel_file_format(record):
        fmt = ["{level} {time:YYYY-MM-DD HH:mm:ss,SSS} "]
        if isinstance(record["extra"].get("channel"), Channels):
            channel = record["extra"]["channel"].name.lower()
            fmt.append(f"[{channel}]")
        if cf.get_int_or_none(record["extra"].get("house")) is not None:
            house_id = cf.get_int_or_none(record["extra"]["house"])
            fmt.append(f"[H:{house_id}]")
        if (record["extra"].get("request_id") or "").strip() != "":
            fmt.append(f'[ParentRID:{record["extra"]["request_id"]}]')
        fmt.append(" {message} \n")

        format_string = "".join(fmt)
        if record.get("exception") is not None:
            format_string += "{exception} \n"
        return format_string
Пример #12
0
 def post(self, request: http.HttpRequest, *args: Any,
          **kwargs: Any) -> http.HttpResponse:
     pk = cf.get_int_or_none(self.kwargs['pk']) or 0
     if pk <= 0:
         raise http.Http404('Missed or wrong Reservation ID')
     return self.process_usecase(CancelReservation, self.kwargs['hid'], pk,
                                 request.user)
Пример #13
0
 def get_house_log_name(routing: Dict[str, Any]) -> str:
     if not isinstance(routing.get("channel"), Channels):
         return ""
     channel = routing["channel"].name.lower()
     house_id = cf.get_int_or_none(routing.get("house"))
     if house_id is None:
         return ""
     return f"ch-{house_id}-{channel}"
Пример #14
0
    def model_to_reservation(self,
                             model: ReservationModel,
                             with_deleted_rooms: bool = False) -> Reservation:
        if model.guest_contact_ids is not None and model.guest_contact_ids != '':
            contact_ids = [
                cf.get_int_or_none(x)
                for x in model.guest_contact_ids.split(',')
            ]
            contact_ids = [x for x in contact_ids if x is not None and x > 0]
        else:
            contact_ids = []
        reservation = Reservation(
            id=model.pk,
            house_id=model.house_id,  # noqa
            connection_id=model.connection.id
            if model.connection is not None else None,
            source=ReservationSources.get_by_name(model.source),
            channel=Channels.get_by_name(model.channel),
            channel_id=model.channel_id,
            status=ReservationStatuses.get_by_name(model.status),
            close_reason=RoomCloseReasons.get_by_name(model.close_reason),
            checkin=model.checkin,
            checkout=model.checkout,
            room_count=model.room_count,
            currency=model.currency,
            price=model.price,
            price_accepted=model.price_accepted,
            tax=model.tax,
            fees=model.fees,
            netto_price=model.netto_price,
            netto_price_accepted=model.netto_price_accepted,
            guest_name=model.guest_name,
            guest_surname=model.guest_surname,
            guest_email=model.guest_email,
            guest_phone=model.guest_phone,
            guest_country=model.guest_country,
            guest_nationality=model.guest_nationality,
            guest_city=model.guest_city,
            guest_address=model.guest_address,
            guest_post_code=model.guest_post_code,
            guest_comments=model.guest_comments,
            guest_contact_id=model.guest_contact_id,
            guest_contact_ids=contact_ids,
            promo=model.promo,
            creditcard_info=model.creditcard_info,
            payment_info=model.payment_info,
            booked_at=model.booked_at,
            is_verified=model.is_verified,
            opportunity_id=model.opportunity_id,
            quotation_id=model.quotation_id,
        )

        queryset = model.rooms.all(
        ) if with_deleted_rooms else model.rooms.active()  # noqa
        for room in queryset:
            reservation.rooms.append(self.model_to_reservation_room(room))
        return reservation
Пример #15
0
 def get_context_data(self,
                      ctx: 'ReservationDetailsContext' = None,
                      **kwargs: Any) -> Dict[str, Any]:
     context = super().get_context_data(**kwargs)
     context.update(ctx.asdict())
     context['CURRENT_HOUSE'] = ctx.house
     context['reservation_rooms'] = self.prepare_rooms(ctx.reservation)
     context['guest_id'] = cf.get_int_or_none(
         self.request.GET.get('guest_id'))  # noqa
     context[
         'pending_balance'] = ctx.reservation.price_accepted - ctx.payed_amount
     return context
Пример #16
0
 def parse_rooms(
         data: Dict[str, Any]) -> Tuple[Optional[int], Optional[int]]:
     grid = data.get('grid', '').strip().lower()
     grid_id = cf.get_int_or_none(data.get('grid_id')) or 0
     if grid == 'roomtype':
         if grid_id <= 0:
             raise http.Http404('Unknown Room Type ID')
         return grid_id, None
     elif grid == 'room':
         if grid_id <= 0:
             raise http.Http404('Unknown Room ID')
         return None, grid_id
     return None, None
 def execute(self, pk: str, house_id: int,
             user: '******') -> ResultE['Reservation']:
     pk = cf.get_int_or_none((pk or '').split('-')[0]) or 0
     ctx = Context(pk=pk, house_id=house_id, user=user)
     return flow(
         ctx,
         self.select_house,
         bind_result(self.select_reservation),
         bind_result(self.check_reservation),
         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 select_reservation_room(self, ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.room_id) or 0
     if pk <= 0:
         return self._error('Missed Reservation Room ID', ctx,
                            self._case_errors.missed_reservation)
     rooms = {x.id: x for x in ctx.reservation.rooms}
     if pk not in rooms:
         return self._error(
             f"Unknown Room ID={pk} in Reservation ID={ctx.reservation.id} House ID={ctx.house.id}",
             ctx,
             self._case_errors.missed_reservation,
         )
     ctx.reservation_room = rooms[pk]
     return Success(ctx)
 def get(
     self,
     house_id: int,
     roomtype_id: int,
     dates: Union[datetime.date, List[datetime.date]],
 ) -> Dict[datetime.date, Optional[int]]:
     if isinstance(dates, datetime.date):
         dates = [dates]
     if not isinstance(dates, list):
         raise AssertionError("Wrong input for OccupancyRepo.get")
     name = cache_keys.occupancy(house_id, roomtype_id)
     result = self.get_store().hmget(name,
                                     [self.format_date(x) for x in dates])
     return {x: cf.get_int_or_none(y) for x, y in zip(dates, result)}
 def post(self, request: http.HttpRequest, *args: Any,
          **kwargs: Any) -> http.HttpResponse:
     data = request.POST.dict()  # noqa
     plan_id = cf.get_int_or_none(data.get('rate_plan')) or 0
     if plan_id <= 0:
         return self.json_error(_('agenda:plan:error'))
     return self.process_usecase(
         UpdateReservationPrices,
         self.kwargs['hid'],
         self.kwargs['pk'],
         self.kwargs['rid'],
         plan_id,
         request.user,
         self.parse_price_data(data),
     )
 def select_rate_plan(self, ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.plan_id) or 0
     if pk <= 0:
         return self._error('Missed Rate Plan ID', ctx, self._case_errors.missed_rateplan)
     try:
         data = self._prices_repo.get_plan(ctx.house.odoo_id, pk, user=ctx.user)
     except Exception as err:
         return self._error(
             f"Error select Rate Plan ID={pk} in House ID={ctx.house.id}", ctx, self._case_errors.error, exc=err
         )
     if data == Nothing:
         return self._error(
             f"Unknown Rate Plan ID={pk} in House ID={ctx.house.id}", ctx, self._case_errors.missed_rateplan
         )
     ctx.rate_plan = data.unwrap()
     return Success(ctx)
    def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse:
        data = request.POST.dict()  # noqa
        period = cf.parse_period(data.get('period', ''))
        if period == Nothing:
            return self.json_error(_('agenda:period:error'))
        start_date, end_date = period.unwrap()
        room_id = cf.get_int_or_none(data.get('room')) or 0
        if room_id <= 0:
            return self.json_error(_('agenda:room:error'))
        reason = RoomCloseReasons.get_by_name(data.get('status', ''))
        if reason is None:
            return self.json_error(_('agenda:status:error'))
        notes = data.get('notes', '')

        return self.process_usecase(
            CreateRoomClose, self.kwargs['hid'], room_id, start_date, end_date, reason, request.user, notes=notes
        )
Пример #23
0
 def select_room_type(
         self,
         ctx: dataclasses.dataclass) -> ResultE[dataclasses.dataclass]:
     pk = cf.get_int_or_none(ctx.roomtype_id) or 0
     if pk <= 0:
         return self._error('Wrong Room Type ID', ctx,
                            self._case_errors.missed_roomtype)
     try:
         data = self._roomtypes_repo.get(ctx.house, pk, user=ctx.user)
     except Exception as err:
         return self._error(f"Error select Room Type ID={pk}",
                            ctx,
                            self._case_errors.error,
                            exc=err)
     if data == Nothing:
         return self._error(f"Unknown Room Type ID={pk}", ctx,
                            self._case_errors.missed_roomtype)
     ctx.room_type = data.unwrap()
     return Success(ctx)
 def select_room_type(self, ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.request.roomtype_id) or 0
     if pk <= 0:
         return self._error('Missed Room Type ID', ctx,
                            self._case_errors.missed_roomtype)
     try:
         data = self._roomtypes_repo.get(ctx.house, pk=pk, user=ctx.user)
         if data == Nothing:
             return self._error(
                 f"Unknown Room Type ID={pk} in House ID={ctx.house.id}",
                 ctx, self._case_errors.missed_roomtype)
     except Exception as err:
         return self._error(
             f"Error select Room Type ID={pk} in House ID={ctx.house.id}",
             ctx,
             self._case_errors.error,
             exc=err)
     ctx.room_type = data.unwrap()
     return Success(ctx)
Пример #25
0
 def select_reservation(self, ctx: dataclasses.dataclass) -> ResultE[dataclasses.dataclass]:
     """Select reservation from Repository and check if it is acceptable"""
     pk = cf.get_int_or_none(ctx.pk) or 0
     if pk <= 0:
         return self._error('Missed Reservation ID', ctx, ReservationErrors.missed_reservation)
     try:
         data = self._reservations_repo.get(pk)
     except Exception as err:
         return self._error(
             f"Error select Reservation ID={pk} in House ID={ctx.house.id}", ctx, ReservationErrors.error, exc=err
         )
     if data == Nothing:
         return self._error(
             f"Unknown Reservation ID={pk} in House ID={ctx.house.id}", ctx, ReservationErrors.missed_reservation
         )
     if hasattr(ctx, 'source'):
         ctx.source = data.unwrap()
     else:
         ctx.reservation = data.unwrap()
     return Success(ctx)
 def parse_price_data(
         data: Dict[str, Any]) -> Dict[datetime.date, Dict[str, Any]]:
     result = {}
     pattern = re.compile(r'\[(\d{4}-\d{2}-\d{2})]')
     for key, value in data.items():
         if not key.startswith('room[') and not key.startswith('price['):
             continue
         match = pattern.search(key)
         if match is None:
             continue
         day = cf.get_date_or_none(match.group(1))
         if day is None:
             continue
         if day not in result:
             result[day] = {'room': None, 'price': None, 'day': day}
         if key.startswith('room['):
             result[day]['room'] = cf.get_int_or_none(value)
         elif key.startswith('price['):
             result[day]['price'] = cf.get_decimal_or_none(value)
     return result
Пример #27
0
 def select_reservation_from_db(self, ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.reservation_id) or 0
     if pk <= 0:
         return self._error('Missed Reservation ID', ctx,
                            self._case_errors.missed_reservation)
     try:
         data = self._reservations_repo.get(pk)
     except Exception as err:
         return self._error(f"Error select Reservation ID={pk}",
                            ctx,
                            self._case_errors.error,
                            exc=err)
     if data == Nothing:
         return self._error(f"Unknown Reservation ID={pk}", ctx,
                            self._case_errors.missed_reservation)
     ctx.reservation = data.unwrap()
     if ctx.reservation.status == ReservationStatuses.CANCEL:
         return self._error(f"Reservation ID={pk} is cancelled", ctx,
                            self._case_errors.missed_reservation)
     return Success(ctx)
Пример #28
0
 def select_user(self, ctx: Context) -> ResultE[Context]:
     pk = cf.get_int_or_none(ctx.user_id) or 0
     try:
         if pk > 0:
             data = self._members_repo.get_user_by_id(pk)
         else:
             data = self._members_repo.get_bot_user(ctx.house.company.id)
     except Exception as err:
         return self._error(
             f"Error select User ID={pk} in Company ID={ctx.house.company.id}",
             ctx,
             self._case_errors.missed_user,
             exc=err,
         )
     if data == Nothing:
         return self._error(
             f"Unknown User ID={pk} in Company ID={ctx.house.company.id}",
             ctx, self._case_errors.missed_user)
     ctx.user = data.unwrap()
     return Success(ctx)
Пример #29
0
 def select_room(self, ctx: Context) -> ResultE[Context]:
     if ctx.room_id is None:
         return Success(ctx)
     pk = cf.get_int_or_none(ctx.room_id) or 0
     if pk <= 0:
         return self._error('Wrong 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()
     return Success(ctx)
Пример #30
0
    def post(self, request: http.HttpRequest, *args: Any,
             **kwargs: Any) -> http.HttpResponse:
        data = request.POST.dict()  # noqa
        pk = data.get('pk', '').strip()
        if pk == '' or '-' not in pk:
            return self.json_error(_('common.error:system'))

        self._reservation_id = cf.get_int_or_none(data.get('rid')) or 0
        if self._reservation_id <= 0:
            return self.json_error(_('agenda:error:unknown_reservation'))

        roomtype_id, room_id = self.parse_rooms(data)

        return self.process_usecase(
            MoveReservation,
            pk,
            self._reservation_id,
            self.kwargs['hid'],
            roomtype_id=roomtype_id,
            room_id=room_id,
            user=request.user,
        )