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 import re from account.decorators import login_required from .models import Product, SeasonRegionMaterial from procat2.models import Season, Region log = logging.getLogger(__name__) @csrf_exempt @login_required @require_http_methods(["POST"]) def search_products(request): body = request.body if not body or len(body) < 1: return HttpResponse('Bad request: no data', status=400) data = json.loads(body.decode('utf-8')) text = data.get('text') if not text or len(text) < 1: return HttpResponse('Bad request: no search text', status=400) season_id = data.get('season') if not season_id or len(season_id) < 1: return HttpResponse('Bad request: no season id', status=400) season = Season.objects.get(id=season_id) if not season: return HttpResponse('Bad request: no season found', status=400) region_id = data.get('region') if not region_id or len(region_id) < 1: return HttpResponse('Bad request: no region id', status=400) region = Region.objects.get(id=region_id) if not region: return HttpResponse('Bad request: no region found', status=400) ids = Product.find_sap_ids(text) log.info('found %s ids %s in %s', len(ids), ids, text) final_prods = [] missing_ids = [] restricted_ids = [] if ids: 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.debug('found %s ids: %s', len(srm_ids), srm_ids) # 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) # 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) # 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 final_prods], 'missing': missing_ids, 'restricted': [] #restricted_ids #'load_ids': load_ids } return JsonResponse(out)