diff --git a/products/views.py b/products/views.py index 9ff2f65..3dcc6a4 100644 --- a/products/views.py +++ b/products/views.py @@ -2,6 +2,7 @@ from django.http import HttpResponseRedirect, HttpResponse, JsonResponse from django.shortcuts import render, get_object_or_404 from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods +from django.db import connections import json import logging @@ -44,30 +45,75 @@ def search_products(request): return HttpResponse('Bad request: no region found', status=400) ids = Product.find_sap_ids(text) - log.info('found ids %s in %s', ids, text) + log.info('found %s ids %s in %s', len(ids), ids, text) - prods = [] - missing = [] + final_prods = [] + missing_ids = [] + restricted_ids = [] if ids: - srm = SeasonRegionMaterial.objects.filter(material__in=ids, season=season.id, region__iexact=region.id).distinct('material') + srm = SeasonRegionMaterial.objects.filter(material__in=ids, season=season.id, region__iexact=region.id).order_by('ranking') srm_ids = [x.material for x in srm] - log.info('found SRM ids %s', srm_ids) + log.debug('found %s ids: %s', len(srm_ids), srm_ids) - search_prods = Product.objects.filter(sap__in=srm_ids,season=season.id).distinct('sap') + # in search list but not found in current season/region ranking + missing_ids = (list(set(ids) - set(srm_ids))) + log.debug('no season/region hits on %s ids: %s', len(missing_ids), missing_ids) - # fix product order to match input ids and find missing ids - prod_dict = dict([(p.sap, p) for p in search_prods]) + # missing ids ranked *somewhere*. these are our restricted ids. + restricted = SeasonRegionMaterial.objects.filter(material__in=missing_ids).order_by('material').distinct('material') + restricted_ids = [x.material for x in restricted] + log.debug('found %s restricted ids: %s', len(restricted_ids), restricted_ids) - for i in ids: - if prod_dict.get(i): - prods.append(prod_dict[i]) - else: - missing.append(i) + # don't include restricted in the missing list + missing_ids = (list(set(missing_ids) - set(restricted_ids))) + log.debug('actually missing %s ids: %s', len(missing_ids), missing_ids) + + # load product info for current season + load_ids = srm_ids + restricted_ids + prods = Product.objects.filter(sap__in=load_ids) + #prods = Product.objects.filter(sap__in=srm_ids, season=season.id) + prods_ids = [x.sap for x in prods] + log.debug('loaded %s season products: %s', len(prods), prods_ids) + + # find info for prods ranking in keen_season_region_material + # but not in keen_materials for the current season. in this + # case, fall back to the most recent data we have for the + # prods. if it's (S/R/M) ranked, it should be returned as a + # valid material as per Ed Reilly. + missing_prod_ids = (list(set(srm_ids) - set(prods_ids))) + fill_in_prods = [] + if missing_prod_ids: + log.debug('looking for %s out-of-season products: %s', len(missing_prod_ids), missing_prod_ids) + fill_in_prods = Product.objects.filter(sap__in=missing_prod_ids).order_by('sap', '-season_ranking').distinct('sap') + log.debug('found %s out-of-season products: %s', len(fill_in_prods), [x.sap for x in fill_in_prods]) + + all_prods = list(prods) + list(fill_in_prods) + prod_dict = dict([(p.sap, p) for p in all_prods]) + + # remove related kids who have a parent in the catalog. + # they'll get added automatically to the parent section. + with connections['products'].cursor() as cursor: + cursor.execute('select child from keen_related_kids where parent = any(%s)', [srm_ids]) + for row in cursor.fetchall(): + kid = row[0] + if kid in prod_dict: + log.debug('removing related kid: %s', kid) + del prod_dict[kid] + + # fix product order to match srm ranking + #for id in srm_ids: + for id in load_ids: + if prod_dict.get(id): + final_prods.append(prod_dict[id]) + + log.debug('returning %s products: %s', len(final_prods), [x.sap for x in final_prods]) out = { - 'found': [p.serialize() for p in prods], - 'missing': missing, + 'found': [p.serialize() for p in final_prods], + 'missing': missing_ids, + 'restricted': [] #restricted_ids + #'load_ids': load_ids } return JsonResponse(out)