Skip to content

Instantly share code, notes, and snippets.

@sanchojaf
Created June 30, 2021 19:23
Show Gist options
  • Save sanchojaf/d934271842b708e26a6a2a1518b3d068 to your computer and use it in GitHub Desktop.
Save sanchojaf/d934271842b708e26a6a2a1518b3d068 to your computer and use it in GitHub Desktop.
@tenant_context(None)
def get(self, request):
"""
anonymous users:
/menus?day={} and request.session['location']['route_id'] must be set to route id
/menus?key={}
loggedin users:
/menus?day={}
/menus?day={}&location_id={}
/menus?date={}
/menus?date={}&location_id={}
staff users:
/menus?date={}&hub={}
optional parameters:
preview - show all items regardless of soldouts
ignore_closes - return menu without checking for blackout/closes for location
required parameters:
menu_type - individual, group, extra, invite
"""
day = request.GET.get('day', None)
date = request.GET.get('date', None)
location_id = request.GET.get('location_id', None)
hub_short_name = request.GET.get('hub', None)
tenant_slug = request.GET.get('tenant_slug', None)
key = request.GET.get('key', None)
menu_type = request.GET.get('menu_type', RequestMenuType.INDIVIDUAL)
ignore_inventory = 'ignore_inventory' in request.GET
ignore_closes = 'ignore_closes' in request.GET
route = None
try:
if (
(day is None or int(day) not in list(range(1, 6)))
and not date
and not key
):
return HttpResponseBadRequest("Invalid or missing day given")
except ValueError:
return HttpResponseBadRequest("Invalid or missing day given")
restaurant_id = None
if menu_type == RequestMenuType.BRAND:
try:
restaurant_id = Restaurant.objects.get(
slug=request.GET.get('restaurant_slug', None)
).id
except Restaurant.DoesNotExist:
return HttpResponseBadRequest("Invalid restaurant slug provided")
day = int(day) if day else None
if day:
if request.user.is_authenticated:
user_profile = request.user.userprofile
menu_date = menu_dates(
cutoff_info=user_profile.get_order_cutoff_info(),
right_now=get_datetime_for_timezone(
timezone.now(), user_profile.get_timezone()
),
)[day - 1]
else:
route = Route.get_from_request(request)
if not route:
return HttpResponseBadRequest("No route found")
menu_date = menu_dates(
cutoff_info=route.hub.get_order_cutoff_info(),
right_now=get_datetime_for_timezone(
timezone.now(), route.hub.get_timezone()
),
)[day - 1]
elif date:
try:
menu_date = parse(date).date()
except:
return HttpResponseBadRequest("Could not parse date")
elif key:
menu_type = RequestMenuType.INVITEE
meeting = Meeting.get_meeting_from_invitee_key(str(key))
route = meeting.order.location.route
location_id = meeting.order.location_id
menu_date = meeting.date
else:
return HttpResponseBadRequest("Must give day or date or key")
response_data = {
'date': menu_date
} # required when we don't go through menu serializer
location = None
if location_id or request.user.is_authenticated:
location_id = (
location_id if location_id else request.user.userprofile.location.id
)
try:
location = Location.objects.get(id=location_id)
except Location.DoesNotExist:
return HttpResponseBadRequest(
"No location found for {}".format(location_id)
)
if menu_date:
location = LocationMigration.get_migrated_location(location, menu_date)
response_data['location_id'] = location_id
# Fill response data in the context of the operator associated with given location or route
# in case user is logged into a different tenant than invite order
hub = None
# We want menu previews to fall back to using the hub shortname and tenant slug
if location and menu_type != RequestMenuType.PREVIEW:
operator = location.operator
elif route:
operator = route.operator
elif hub_short_name:
try:
hub = Hub.objects.get(
short_name=hub_short_name, operator__slug=tenant_slug
)
operator = hub.operator
except Hub.DoesNotExist:
return HttpResponseBadRequest("No hub found")
else:
logger.warning("Cannot determine tenant for /menu/ request")
return HttpResponseBadRequest("Unknown tenant")
with tenant_context(operator):
menu = None
menu_status = None
if request.user.is_authenticated and not hub_short_name:
response_data['company'] = request.user.userprofile.company.name
menu_data = get_upcoming_menus(
request.user.userprofile, location=location, menu_date=menu_date
)
if menu_data.get('menus', None):
menu = menu_data.get('menus')[0]
menu_status = menu_data.get('menu_types')[0][1]
if (
menu_status == 'holiday'
or not ignore_closes
and menu_status in ['closed', 'blackout']
):
# The caller of the API can choose to ignore closed dates, but it should be only applicable for
# company-based closures, ex. closed menu, blackouts; for holidays we should disregard the param value
response_data[menu_status] = True
if menu_status == 'holiday':
response_data.update(
{
'holiday': HolidaySerializer(
Holiday.filter_holidays_by_date(menu_date).first()
).data
}
)
return JSONResponse(response_data)
if not menu:
try:
if hub:
hub_id = hub.id
elif route:
hub_id = route.hub_id
response_data['route_id'] = route.id
elif location:
hub_id = location.route.hub_id
else:
hub_id = request.user.userprofile.location.route.hub_id
menu = Menu.objects.get(hub=hub_id, date=menu_date)
except Menu.DoesNotExist:
holiday = Holiday.filter_holidays_by_date(
menu_date
) # ignore holiday exempts since user is not authenticated
if holiday:
response_data.update(
{'holiday': HolidaySerializer(holiday.first()).data}
)
return JSONResponse(response_data)
logger.warning(
'MISSING MENU: status:{}, location:{}, menu_date: {}'.format(
menu_status, location, menu_date
)
)
return HttpResponseBadRequest("Menu not found")
except Location.DoesNotExist:
return HttpResponseBadRequest("Location not found")
userprofile = None
if request.user.is_authenticated:
userprofile = request.user.userprofile
menu = MenuSerializer.prepare(Menu.objects.filter(id__in=[menu.id]))
secret_menu_types = [RequestMenuType.INDIVIDUAL, RequestMenuType.EXTRAS]
context = MenuSerializer.create_context(
menu,
userprofile,
make_hidden_prices_false=True,
hide_secret_menu=(menu_type not in secret_menu_types),
menu_type=menu_type,
ignore_inventory=ignore_inventory,
restaurant_id=restaurant_id,
)
context['categorized_menu'] = request.GET.get('categorized_menu', False)
context['visit_id'] = request.visit_id
serializer = MenuSerializer(menu, context=context, many=True)
response_data.update(serializer.data[0])
if not request.GET.get('categorized_menu', False):
response_data = trim_menu_items(response_data)
return Response(response_data, status=status.HTTP_200_OK)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment