def delete(request, employee_id): """ This will also remove the employee from the ACL, delete the employee object and also delete the Parse.User object if and only if it has no pointer to a Store or a Patron. """ # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) i_remove, employee = 0, None for ind, m in enumerate(employees_approved_list): if m.objectId == employee_id: employee = m i_remove = ind break if not employee: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been removed.'})) employees_approved_list.pop(i_remove) request.session['employees_approved_list'] =\ employees_approved_list acc = Account.objects().get(Employee=employee.objectId) if not acc: # employee may have been deleted return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been deleted.'})) # Always save session first whenever calling a cloud code request.session.save() res = cloud_call("delete_employee", {"employee_id": employee.objectId}) request.session.clear() request.session.update(SessionStore(request.session.session_key)) if 'error' not in res: store = SESSION.get_store(request.session) payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY } if acc.objectId in store.ACL and not store.is_owner(acc): del store.ACL[acc.objectId] store.update() payload["updatedStore"] = store.jsonify() request.session['store'] = store # only need to pass in the objectId deleted_employee = Employee(objectId=employee.objectId) payload["deletedEmployee"] = deleted_employee.jsonify() comet_receive(store.objectId, payload) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has been deleted.'})) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been deleted.'}))
def delete(request, employee_id): """ This will also remove the employee from the ACL, delete the employee object and also delete the Parse.User object if and only if it has no pointer to a Store or a Patron. """ # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) i_remove, employee = 0, None for ind, m in enumerate(employees_approved_list): if m.objectId == employee_id: employee = m i_remove = ind break if not employee: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been removed.'})) employees_approved_list.pop(i_remove) request.session['employees_approved_list'] =\ employees_approved_list acc = Account.objects().get(Employee=employee.objectId) if not acc: # employee may have been deleted return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been deleted.'})) # Always save session first whenever calling a cloud code request.session.save() res = cloud_call("delete_employee", {"employee_id": employee.objectId}) request.session.clear() request.session.update(SessionStore(request.session.session_key)) if 'error' not in res: store = SESSION.get_store(request.session) payload = {COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY} if acc.objectId in store.ACL and not store.is_owner(acc): del store.ACL[acc.objectId] store.update() payload["updatedStore"] = store.jsonify() request.session['store'] = store # only need to pass in the objectId deleted_employee = Employee(objectId=employee.objectId) payload["deletedEmployee"] = deleted_employee.jsonify() comet_receive(store.objectId, payload) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has been deleted.'})) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has already been deleted.'}))
def index(request): data = {'employees_nav': True} data['pending'] =\ SESSION.get_employees_pending_list(request.session) data['employees'] =\ SESSION.get_employees_approved_list(request.session) data['show_pending'] = (request.GET.get("show_pending") is not None) if request.GET.get("success"): data['success'] = request.GET.get("success") if request.GET.get("error"): data['error'] = request.GET.get("error") return render(request, 'manage/employees.djhtml', data)
def index(request): data = {'employees_nav': True} data['pending'] =\ SESSION.get_employees_pending_list(request.session) data['employees'] =\ SESSION.get_employees_approved_list(request.session) data['show_pending'] = (request.GET.get("show_pending") is not None); if request.GET.get("success"): data['success'] = request.GET.get("success") if request.GET.get("error"): data['error'] = request.GET.get("error") return render(request, 'manage/employees.djhtml', data)
def edit(request, employee_id): data = {'employees_nav': True, 'employee_id': employee_id} # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employee = None for m in employees_approved_list: if m.objectId == employee_id: employee = m break acc = Account.objects().get(Employee=employee.objectId) store = SESSION.get_store(request.session) if not employee or not acc: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee does not exist.'})) if request.method == "POST": store.set_access_level(acc, request.POST["ACL"]) store.update() request.session['store'] = store # notify other dashboards of this change payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "updatedStore": store.jsonify() } comet_receive(store.objectId, payload) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has been updated.'})) form = EmployeeForm(employee.__dict__.copy()) form.data['email'] = acc.get('email') data.update({ 'ACCESS_ADMIN': ACCESS_ADMIN[0], 'ACCESS_PUNCHREDEEM': ACCESS_PUNCHREDEEM[0], 'ACCESS_NONE': ACCESS_NONE[0], 'form': form, 'employee': employee, 'employee_acl': store.get_access_level(acc)[0], }) return render(request, 'manage/employee_edit.djhtml', data)
def edit(request, employee_id): data = {'employees_nav': True, 'employee_id': employee_id} # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employee = None for m in employees_approved_list: if m.objectId == employee_id: employee = m break acc = Account.objects().get(Employee=employee.objectId) store = SESSION.get_store(request.session) if not employee or not acc: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee does not exist.'})) if request.method == "POST": store.set_access_level(acc, request.POST["ACL"]) store.update() request.session['store'] = store # notify other dashboards of this change payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "updatedStore":store.jsonify() } comet_receive(store.objectId, payload) return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Employee has been updated.'})) form = EmployeeForm(employee.__dict__.copy()) form.data['email'] = acc.get('email') data.update({ 'ACCESS_ADMIN': ACCESS_ADMIN[0], 'ACCESS_PUNCHREDEEM': ACCESS_PUNCHREDEEM[0], 'ACCESS_NONE': ACCESS_NONE[0], 'form': form, 'employee': employee, 'employee_acl': store.get_access_level(acc)[0], }) return render(request, 'manage/employee_edit.djhtml', data)
def punches(request, employee_id): data = {'employee_id': employee_id} # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employee = None for ind, m in enumerate(employees_approved_list): if m.objectId == employee_id: employee = m break if not employee: raise Http404 # page starts at 1 page = int(request.GET.get('page')) order_by = request.POST.get('order_by') order_dir = request.POST.get('order_dir') if order_dir != None and order_dir.lower() == 'desc': order_by = '-' + order_by # limit is +1 to find out if has_next limit = PAGINATION_THRESHOLD + 1 skip = (page - 1) * PAGINATION_THRESHOLD employee.set("punches", None) punches = employee.get('punches', include="Patron", order=order_by, limit=limit, skip=skip) # make sure to pop the PAGINATION_THRESHOLD + 1 row if exist if punches and len(punches) > PAGINATION_THRESHOLD: punches.pop() data['next_page_number'] = page + 1 data['punches'] = punches return render(request, 'manage/employee_punches.djhtml', data)
def approve(request, employee_id): # get from the employees_pending_list in session cache employees_pending_list = SESSION.get_employees_pending_list(\ request.session) i_remove, employee = 0, None for ind, m in enumerate(employees_pending_list): if m.objectId == employee_id: employee = m i_remove = ind break if not employee: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Pending employee not found.'})) employee.set('status', APPROVED) employee.update() employees_pending_list.pop(i_remove) request.session['employees_pending_list'] =\ employees_pending_list # update session cache for employees_approved_list employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employees_approved_list.insert(0, employee) request.session['employees_approved_list'] =\ employees_approved_list # notify other dashboards of this change store_id = SESSION.get_store(request.session).objectId approved_employee = Employee(objectId=employee.objectId) payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "approvedEmployee": approved_employee.jsonify() } comet_receive(store_id, payload) return redirect(reverse('employees_index')+ "?show_pending&%s" %\ urllib.urlencode({'success': 'Employee has been approved.'}))
def approve(request, employee_id): # get from the employees_pending_list in session cache employees_pending_list = SESSION.get_employees_pending_list(\ request.session) i_remove, employee = 0, None for ind, m in enumerate(employees_pending_list): if m.objectId == employee_id: employee = m i_remove = ind break if not employee: return redirect(reverse('employees_index')+ "?%s" %\ urllib.urlencode({'success': 'Pending employee not found.'})) employee.set('status', APPROVED) employee.update() employees_pending_list.pop(i_remove) request.session['employees_pending_list'] =\ employees_pending_list # update session cache for employees_approved_list employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employees_approved_list.insert(0, employee) request.session['employees_approved_list'] =\ employees_approved_list # notify other dashboards of this change store_id = SESSION.get_store(request.session).objectId approved_employee = Employee(objectId=employee.objectId) payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "approvedEmployee":approved_employee.jsonify() } comet_receive(store_id, payload) return redirect(reverse('employees_index')+ "?show_pending&%s" %\ urllib.urlencode({'success': 'Employee has been approved.'}))
def punches(request, employee_id): data = {'employee_id': employee_id} # get from the employees_approved_list in session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employee = None for ind, m in enumerate(employees_approved_list): if m.objectId == employee_id: employee = m break if not employee: raise Http404 # page starts at 1 page = int(request.GET.get('page')) order_by = request.POST.get('order_by') order_dir = request.POST.get('order_dir') if order_dir != None and order_dir.lower() == 'desc': order_by = '-'+order_by # limit is +1 to find out if has_next limit = PAGINATION_THRESHOLD + 1 skip = (page-1) * PAGINATION_THRESHOLD employee.set("punches", None) punches = employee.get('punches', include="Patron", order=order_by, limit=limit, skip=skip) # make sure to pop the PAGINATION_THRESHOLD + 1 row if exist if punches and len(punches) > PAGINATION_THRESHOLD: punches.pop() data['next_page_number'] = page + 1 data['punches'] = punches return render(request, 'manage/employee_punches.djhtml', data)
def register(request): """ Adds a new employee to the currently logged in Store. This automatically sets this employee to approved. """ data = {'employees_nav': True} settings = SESSION.get_settings(request.session) store = SESSION.get_store(request.session) if request.method == "POST": from_associated_account = False # check if this post is from the associated account dialog # if it is then skip form validations aaf_nonce_id = request.POST.get('aaf-nonce') aaf_account_id = request.POST.get('aaf-account_id') if len(aaf_nonce_id) > 0 and len(aaf_account_id) > 0: aa_nonce = AssociatedAccountNonce.objects.filter(\ id=aaf_nonce_id, account_id=aaf_account_id) if len(aa_nonce) > 0 and aa_nonce[0].verified: aa_nonce[0].delete() from_associated_account = True account_form = EmployeeAccountSignUpForm(request.POST) employee_form = EmployeeForm(request.POST) if not from_associated_account: all_forms_valid = account_form.is_valid() and\ employee_form.is_valid() else: all_forms_valid = True if all_forms_valid: postDict = request.POST.dict() # make the cloud call # see cloud param for possible access level values acl = postDict['acl'] if acl == ACCESS_ADMIN[0]: access_level = "admin" elif acl == ACCESS_PUNCHREDEEM[0]: access_level = "punch_redeem" else: access_level = None params = { "retailer_pin": settings.get("retailer_pin"), "username": postDict['email'].strip().lower(), "first_name": postDict['first_name'].capitalize(), "last_name": postDict['last_name'].capitalize(), "email": postDict['email'].strip().lower(), "status": APPROVED, "access_level": access_level, } if from_associated_account: res = cloud_call("link_employee", params) else: params["password"] = postDict['password'] res = cloud_call("register_employee", params) # don't forget to retrieve the latest session request.session.clear() request.session.update(SessionStore(request.session.session_key)) # check if email already taken here to handle the case where # the user already has a patron/employee account # but also want to sign up for a Store account if "error" in res and res['error'] in ("EMAIL_TAKEN_AVAILABLE", "USERNAME_TAKEN_AVAILABLE"): aa = Account.objects().get( email=postDict['email'].strip().lower()) aan = AssociatedAccountNonce.objects.create(\ account_id=aa.objectId) return HttpResponse(json.dumps({"associated_account":\ aa.objectId, "associated_account_nonce":aan.id, "email": aa.email, "code": 0}), content_type="application/json") elif "error" in res and res['error'] in ("EMAIL_TAKEN", "USERNAME_TAKEN"): account_form._errors.setdefault( "email", ErrorList()).append(u"Email is already being used.") elif "error" not in res: # add the employee to the approved list employees_approved_list =\ SESSION.get_employees_approved_list(request.session) employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] new_employee = Employee(**res["result"]) if new_employee.objectId not in employees_approved_ids: employees_approved_list.insert(0, new_employee) request.session['employees_approved_list'] =\ employees_approved_list # update our local store's acl - don't wait for # the cloud post store = SESSION.get_store(request.session) store.set_access_level(Account.objects().get(\ email=postDict['email'].strip().lower()), acl) request.session['store'] = store # notify other dashboards of this change payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "updatedStore": store.jsonify() } comet_receive(store.objectId, payload) return HttpResponse(json.dumps({"code": 2}), content_type="application/json") else: return HttpResponse(json.dumps({"code": 3}), content_type="application/json") else: employee_form = EmployeeForm(initial={"acl":\ ACCESS_PUNCHREDEEM[0]}) account_form = EmployeeAccountSignUpForm() data["employee_form"] = employee_form data["account_form"] = account_form return render(request, 'manage/employee_register.djhtml', data)
def graph(request): store_timezone = SESSION.get_store_timezone(request.session) employee_ids = request.GET.getlist('employee[]') start = request.GET.get('start') end = request.GET.get('end') start = datetime.strptime(start, "%m/%d/%Y") start = start.replace(hour=0, minute=0, second=0, microsecond=0) end = datetime.strptime(end, "%m/%d/%Y") end = end.replace(hour=23, minute=59, second=59, microsecond=0) # need to make aware and then convert to utc for querying start_aware = make_aware_to_utc(start, store_timezone) end_aware = make_aware_to_utc(end, store_timezone) columns = [{"id": "", "label": "Date", "type": "string"}] # build the list of employees from the list in the session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employees = [] for ind, m in enumerate(employees_approved_list): if m.objectId in employee_ids: employees.append(m) if employees: for emp in employees: columns.append({"id":"", "label":emp.get('first_name')+\ ' '+emp.get('last_name'), "type":"number"}) punch_map = {} # since a punch no longer contains a pointer to an employee # the query must be made in the punches for each employee... if employees: for emp in employees: ps = emp.get('punches', createdAt__gte=start_aware, createdAt__lte=end_aware) if ps: for punch in ps: key = timezone.localtime(punch.createdAt, store_timezone).strftime("%m/%d")+'-'+\ emp.objectId if key in punch_map: punch_map[key] = punch_map[key] +\ punch.get('punches') else: punch_map[key] = punch.get('punches') rows = [] for single_date in rputils.daterange(start, end): str_date = make_aware_to_utc(single_date, store_timezone).strftime("%m/%d") c = [{"v": str_date}] for emp in employees: try: punch_count = punch_map[str_date + '-' + emp.objectId] except KeyError: punch_count = 0 c.append({"v": punch_count}) rows.append({'c': c}) return HttpResponse(json.dumps({ 'cols': columns, 'rows': rows }), content_type="application/json")
def comet(session_copy): # used by more than 1 (note that it is ok to retrieve all of # the lists since they are all pointers - not the actual list! employees_pending_list_copy =\ SESSION.get_employees_pending_list(session_copy) employees_approved_list_copy =\ SESSION.get_employees_approved_list(session_copy) messages_received_list_copy =\ SESSION.get_messages_received_list(session_copy) redemptions_pending_copy =\ SESSION.get_redemptions_pending(session_copy) redemptions_past_copy =\ SESSION.get_redemptions_past(session_copy) # this is the latest session data session = SessionStore(request.session.session_key) employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) # put the diffs between session_copy and session here data = {} ############################################################# # FEEDBACKS_UNREAD ################################## fbs_unread_copy = [ fb.objectId for fb in\ messages_received_list_copy if not fb.is_read ] fbs_unread = [ fb.objectId for fb in\ messages_received_list if not fb.is_read ] # get the difference between the two feedbacks_unread =\ tuple(set(fbs_unread) - set(fbs_unread_copy)) if feedbacks_unread: fb_unread = [] messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] for feedback_id in feedbacks_unread: for fb in messages_received_list: if fb.objectId == feedback_id: fb_unread.append(fb.jsonify()) break if len(fb_unread) > 0: fb_count = 0 for fb in messages_received_list: if not fb.get("is_read"): fb_count += 1 data['feedbacks_unread'] = fb_unread data['feedback_unread_count'] = fb_count ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! emps_pending_copy = [ emp.objectId for emp in employees_pending_list_copy ] emps_pending = [ emp.objectId for emp in employees_pending_list ] employees_pending =\ tuple(set(emps_pending) - set(emps_pending_copy)) if employees_pending: pending = [] for emp_id in employees_pending: for emp in employees_pending_list: if emp.objectId == emp_id: pending.append(emp.jsonify()) break if len(pending) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_pending'] = pending ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# emps_approved_copy = [ emp.objectId for emp in\ employees_approved_list_copy] emps_approved = [ emp.objectId for emp in\ employees_approved_list] appr_emps =\ tuple(set(emps_approved) - set(emps_approved_copy)) if appr_emps: approved = [] for appr_emp_id in appr_emps: for emp in employees_approved_list: if emp.objectId == appr_emp_id: approved.append(emp.jsonify()) break if len(approved) > 0: data['employees_approved'] = approved data['employees_pending_count'] =\ len(employees_pending_list) ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! # need to compare approved and pending! emps_copy = emps_approved_copy[:] emps_copy.extend(emps_pending_copy) emps = emps_approved[:] emps.extend(emps_pending) # emps_copy has the same or more items that emps del_emps = tuple(set(emps_copy) - set(emps)) if del_emps: deleted = [] for demp_id in del_emps: if demp_id in emps_approved_copy: emps_list = employees_approved_list_copy else: emps_list = employees_pending_list_copy for emp in emps_list: if emp.objectId == demp_id: deleted.append(emp.jsonify()) break if len(deleted) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_deleted'] = deleted ############################################################# # REDEMPTIONS PENDING reds_pending_copy = [ r.objectId for r in\ redemptions_pending_copy ] reds_pending = [ r.objectId for r in redemptions_pending ] reds = tuple(set(reds_pending) - set(reds_pending_copy)) if reds: redemps = [] for r_id in reds: for redemp in redemptions_pending: if redemp.objectId == r_id: redemps.append(redemp.jsonify()) break if len(redemps) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_pending'] = redemps ############################################################# # REDEMPTIONS APPROVED (pending to history) reds_past_copy = [ r.objectId for r in\ redemptions_past_copy ] reds_past = [ r.objectId for r in redemptions_past ] appr_redemps =\ tuple(set(reds_past) - set(reds_past_copy)) if appr_redemps: redemp_js = [] for red_id in appr_redemps: for redemp in redemptions_past: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_approved'] = redemp_js ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) reds_copy = reds_past_copy[:] reds_copy.extend(reds_pending_copy) reds = reds_past[:] reds.extend(reds_pending) # reds_copy has the same or more items that reds del_redemps = tuple(set(reds_copy) - set(reds)) if del_redemps: redemp_js = [] for red_id in del_redemps: reds_list = [] if red_id in reds_past_copy: reds_list = redemptions_past_copy elif red_id in reds_pending_copy: reds_list = redemptions_pending_copy for redemp in reds_list: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_deleted'] = redemp_js ############################################################# # SETTINGS UPDATED ############################## settings_copy = session_copy.get("settings") settings = session.get("settings") if settings_copy.get("retailer_pin") !=\ settings.get("retailer_pin"): data['retailer_pin'] = settings.get("retailer_pin") ############################################################# # REWARDS UPDATED ############################## rewards_copy = session_copy.get("store").get("rewards") rewards_copy =\ { reward['reward_id']:reward for reward in rewards_copy } rewards = session.get("store").get("rewards") rewards = { reward['reward_id']:reward for reward in rewards } updated_rewards = [] for reward_id, rew_copy in rewards_copy.iteritems(): # Note that some rewards may have been deleted! rew = rewards.get(reward_id) if rew and rew_copy['redemption_count'] !=\ rew['redemption_count']: # only the redemtpion_count and reward_id are used # in the client side updated_rewards.append({ "reward_id": reward_id, "redemption_count": rew['redemption_count'], }) if updated_rewards: data['rewards'] = updated_rewards ############################################################# # PATRONSTORE_COUNT ################################## patronStore_count_copy =int(session_copy["patronStore_count"]) patronStore_count = int(session["patronStore_count"]) if patronStore_count_copy != patronStore_count: data['patronStore_count'] = patronStore_count ############################################################# # ACTIVE_STORE_LOCATION_ID ############################ if session['active_store_location_id'] !=\ session_copy['active_store_location_id']: data['active_store_location_id'] =\ session['active_store_location_id'] # IMPORTANT! The request.session is the same as the # SessionStore(session_key)! so we must use the # request.session because it is automatically saved at the end # of each request- thereby overriding/undoing any changes made # to the SessionStore(session_key) key! # need to check if we are still logged in session = SessionStore(request.session.session_key) if 'account' in session and SESSION_KEY in session: request.session.clear() request.session.update(session) else: flush(request.session) ############################################################ # Respond ########################################### try: return HttpResponse(json.dumps(data), content_type="application/json") except (IOError, socket.error) as e: # broken pipe/socket. thread.exit() # exit silently
def register(request): """ Adds a new employee to the currently logged in Store. This automatically sets this employee to approved. """ data = {'employees_nav': True} settings = SESSION.get_settings(request.session) store = SESSION.get_store(request.session) if request.method == "POST": from_associated_account = False # check if this post is from the associated account dialog # if it is then skip form validations aaf_nonce_id = request.POST.get('aaf-nonce') aaf_account_id = request.POST.get('aaf-account_id') if len(aaf_nonce_id) > 0 and len(aaf_account_id) > 0: aa_nonce = AssociatedAccountNonce.objects.filter(\ id=aaf_nonce_id, account_id=aaf_account_id) if len(aa_nonce) > 0 and aa_nonce[0].verified: aa_nonce[0].delete() from_associated_account = True account_form = EmployeeAccountSignUpForm(request.POST) employee_form = EmployeeForm(request.POST) if not from_associated_account: all_forms_valid = account_form.is_valid() and\ employee_form.is_valid() else: all_forms_valid = True if all_forms_valid: postDict = request.POST.dict() # make the cloud call # see cloud param for possible access level values acl = postDict['acl'] if acl == ACCESS_ADMIN[0]: access_level = "admin" elif acl == ACCESS_PUNCHREDEEM[0]: access_level = "punch_redeem" else: access_level = None params = { "retailer_pin": settings.get("retailer_pin"), "username": postDict['email'].strip().lower(), "first_name": postDict['first_name'].capitalize(), "last_name": postDict['last_name'].capitalize(), "email": postDict['email'].strip().lower(), "status": APPROVED, "access_level": access_level, } if from_associated_account: res = cloud_call("link_employee", params) else: params["password"] = postDict['password'] res = cloud_call("register_employee", params) # don't forget to retrieve the latest session request.session.clear() request.session.update(SessionStore(request.session.session_key)) # check if email already taken here to handle the case where # the user already has a patron/employee account # but also want to sign up for a Store account if "error" in res and res['error'] in ("EMAIL_TAKEN_AVAILABLE", "USERNAME_TAKEN_AVAILABLE"): aa = Account.objects().get(email=postDict['email'].strip().lower()) aan = AssociatedAccountNonce.objects.create(\ account_id=aa.objectId) return HttpResponse(json.dumps({"associated_account":\ aa.objectId, "associated_account_nonce":aan.id, "email": aa.email, "code": 0}), content_type="application/json") elif "error" in res and res['error'] in ("EMAIL_TAKEN", "USERNAME_TAKEN"): account_form._errors.setdefault("email", ErrorList()).append(u"Email is already being used.") elif "error" not in res: # add the employee to the approved list employees_approved_list =\ SESSION.get_employees_approved_list(request.session) employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] new_employee = Employee(**res["result"]) if new_employee.objectId not in employees_approved_ids: employees_approved_list.insert(0, new_employee) request.session['employees_approved_list'] =\ employees_approved_list # update our local store's acl - don't wait for # the cloud post store = SESSION.get_store(request.session) store.set_access_level(Account.objects().get(\ email=postDict['email'].strip().lower()), acl) request.session['store'] = store # notify other dashboards of this change payload = { COMET_RECEIVE_KEY_NAME: COMET_RECEIVE_KEY, "updatedStore":store.jsonify() } comet_receive(store.objectId, payload) return HttpResponse(json.dumps({"code": 2}), content_type="application/json") else: return HttpResponse(json.dumps({"code": 3}), content_type="application/json") else: employee_form = EmployeeForm(initial={"acl":\ ACCESS_PUNCHREDEEM[0]}) account_form = EmployeeAccountSignUpForm() data["employee_form"] = employee_form data["account_form"] = account_form return render(request, 'manage/employee_register.djhtml', data)
def graph(request): store_timezone = SESSION.get_store_timezone(request.session) employee_ids = request.GET.getlist('employee[]') start = request.GET.get('start') end = request.GET.get('end'); start = datetime.strptime(start, "%m/%d/%Y") start = start.replace(hour=0, minute=0, second=0, microsecond=0) end = datetime.strptime(end, "%m/%d/%Y") end = end.replace(hour=23, minute=59, second=59, microsecond=0) # need to make aware and then convert to utc for querying start_aware = make_aware_to_utc(start, store_timezone) end_aware = make_aware_to_utc(end, store_timezone) columns = [ {"id":"", "label":"Date", "type":"string"} ] # build the list of employees from the list in the session cache employees_approved_list = SESSION.get_employees_approved_list(\ request.session) employees = [] for ind, m in enumerate(employees_approved_list): if m.objectId in employee_ids: employees.append(m) if employees: for emp in employees: columns.append({"id":"", "label":emp.get('first_name')+\ ' '+emp.get('last_name'), "type":"number"}) punch_map = {} # since a punch no longer contains a pointer to an employee # the query must be made in the punches for each employee... if employees: for emp in employees: ps = emp.get('punches', createdAt__gte=start_aware, createdAt__lte=end_aware) if ps: for punch in ps: key = timezone.localtime(punch.createdAt, store_timezone).strftime("%m/%d")+'-'+\ emp.objectId if key in punch_map: punch_map[key] = punch_map[key] +\ punch.get('punches') else: punch_map[key] = punch.get('punches') rows = [] for single_date in rputils.daterange(start, end): str_date = make_aware_to_utc(single_date, store_timezone).strftime("%m/%d") c = [{"v": str_date}] for emp in employees: try: punch_count = punch_map[str_date + '-' + emp.objectId] except KeyError: punch_count = 0 c.append({"v": punch_count}) rows.append({'c': c}) return HttpResponse(json.dumps({'cols': columns, 'rows': rows}), content_type="application/json")
def comet(session_copy): # used by more than 1 (note that it is ok to retrieve all of # the lists since they are all pointers - not the actual list! employees_pending_list_copy =\ SESSION.get_employees_pending_list(session_copy) employees_approved_list_copy =\ SESSION.get_employees_approved_list(session_copy) messages_received_list_copy =\ SESSION.get_messages_received_list(session_copy) redemptions_pending_copy =\ SESSION.get_redemptions_pending(session_copy) redemptions_past_copy =\ SESSION.get_redemptions_past(session_copy) # this is the latest session data session = SessionStore(request.session.session_key) employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) # put the diffs between session_copy and session here data = {} ############################################################# # FEEDBACKS_UNREAD ################################## fbs_unread_copy = [ fb.objectId for fb in\ messages_received_list_copy if not fb.is_read ] fbs_unread = [ fb.objectId for fb in\ messages_received_list if not fb.is_read ] # get the difference between the two feedbacks_unread =\ tuple(set(fbs_unread) - set(fbs_unread_copy)) if feedbacks_unread: fb_unread = [] messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] for feedback_id in feedbacks_unread: for fb in messages_received_list: if fb.objectId == feedback_id: fb_unread.append(fb.jsonify()) break if len(fb_unread) > 0: fb_count = 0 for fb in messages_received_list: if not fb.get("is_read"): fb_count += 1 data['feedbacks_unread'] = fb_unread data['feedback_unread_count'] = fb_count ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! emps_pending_copy = [ emp.objectId for emp in employees_pending_list_copy ] emps_pending = [emp.objectId for emp in employees_pending_list] employees_pending =\ tuple(set(emps_pending) - set(emps_pending_copy)) if employees_pending: pending = [] for emp_id in employees_pending: for emp in employees_pending_list: if emp.objectId == emp_id: pending.append(emp.jsonify()) break if len(pending) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_pending'] = pending ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# emps_approved_copy = [ emp.objectId for emp in\ employees_approved_list_copy] emps_approved = [ emp.objectId for emp in\ employees_approved_list] appr_emps =\ tuple(set(emps_approved) - set(emps_approved_copy)) if appr_emps: approved = [] for appr_emp_id in appr_emps: for emp in employees_approved_list: if emp.objectId == appr_emp_id: approved.append(emp.jsonify()) break if len(approved) > 0: data['employees_approved'] = approved data['employees_pending_count'] =\ len(employees_pending_list) ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! # need to compare approved and pending! emps_copy = emps_approved_copy[:] emps_copy.extend(emps_pending_copy) emps = emps_approved[:] emps.extend(emps_pending) # emps_copy has the same or more items that emps del_emps = tuple(set(emps_copy) - set(emps)) if del_emps: deleted = [] for demp_id in del_emps: if demp_id in emps_approved_copy: emps_list = employees_approved_list_copy else: emps_list = employees_pending_list_copy for emp in emps_list: if emp.objectId == demp_id: deleted.append(emp.jsonify()) break if len(deleted) > 0: data['employees_pending_count'] =\ len(employees_pending_list) data['employees_deleted'] = deleted ############################################################# # REDEMPTIONS PENDING reds_pending_copy = [ r.objectId for r in\ redemptions_pending_copy ] reds_pending = [r.objectId for r in redemptions_pending] reds = tuple(set(reds_pending) - set(reds_pending_copy)) if reds: redemps = [] for r_id in reds: for redemp in redemptions_pending: if redemp.objectId == r_id: redemps.append(redemp.jsonify()) break if len(redemps) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_pending'] = redemps ############################################################# # REDEMPTIONS APPROVED (pending to history) reds_past_copy = [ r.objectId for r in\ redemptions_past_copy ] reds_past = [r.objectId for r in redemptions_past] appr_redemps =\ tuple(set(reds_past) - set(reds_past_copy)) if appr_redemps: redemp_js = [] for red_id in appr_redemps: for redemp in redemptions_past: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_approved'] = redemp_js ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) reds_copy = reds_past_copy[:] reds_copy.extend(reds_pending_copy) reds = reds_past[:] reds.extend(reds_pending) # reds_copy has the same or more items that reds del_redemps = tuple(set(reds_copy) - set(reds)) if del_redemps: redemp_js = [] for red_id in del_redemps: reds_list = [] if red_id in reds_past_copy: reds_list = redemptions_past_copy elif red_id in reds_pending_copy: reds_list = redemptions_pending_copy for redemp in reds_list: if redemp.objectId == red_id: redemp_js.append(redemp.jsonify()) break if len(redemp_js) > 0: data['redemption_pending_count'] =\ len(redemptions_pending) data['redemptions_deleted'] = redemp_js ############################################################# # SETTINGS UPDATED ############################## settings_copy = session_copy.get("settings") settings = session.get("settings") if settings_copy.get("retailer_pin") !=\ settings.get("retailer_pin"): data['retailer_pin'] = settings.get("retailer_pin") ############################################################# # REWARDS UPDATED ############################## rewards_copy = session_copy.get("store").get("rewards") rewards_copy =\ { reward['reward_id']:reward for reward in rewards_copy } rewards = session.get("store").get("rewards") rewards = {reward['reward_id']: reward for reward in rewards} updated_rewards = [] for reward_id, rew_copy in rewards_copy.iteritems(): # Note that some rewards may have been deleted! rew = rewards.get(reward_id) if rew and rew_copy['redemption_count'] !=\ rew['redemption_count']: # only the redemtpion_count and reward_id are used # in the client side updated_rewards.append({ "reward_id": reward_id, "redemption_count": rew['redemption_count'], }) if updated_rewards: data['rewards'] = updated_rewards ############################################################# # PATRONSTORE_COUNT ################################## patronStore_count_copy = int(session_copy["patronStore_count"]) patronStore_count = int(session["patronStore_count"]) if patronStore_count_copy != patronStore_count: data['patronStore_count'] = patronStore_count ############################################################# # ACTIVE_STORE_LOCATION_ID ############################ if session['active_store_location_id'] !=\ session_copy['active_store_location_id']: data['active_store_location_id'] =\ session['active_store_location_id'] # IMPORTANT! The request.session is the same as the # SessionStore(session_key)! so we must use the # request.session because it is automatically saved at the end # of each request- thereby overriding/undoing any changes made # to the SessionStore(session_key) key! # need to check if we are still logged in session = SessionStore(request.session.session_key) if 'account' in session and SESSION_KEY in session: request.session.clear() request.session.update(session) else: flush(request.session) ############################################################ # Respond ########################################### try: return HttpResponse(json.dumps(data), content_type="application/json") except (IOError, socket.error) as e: # broken pipe/socket. thread.exit() # exit silently
def processCometReceivedDict(session, postDict): employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) ############################################################# # FEEDBACKS_UNREAD ################################## newFeedback = postDict.get('newFeedback') if newFeedback: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] m = Message(**newFeedback) if m.objectId not in messages_received_ids: messages_received_list.insert(0, m) session['messages_received_list'] =\ messages_received_list ############################################################# # FEEDBACK DELETED ################################## deletedFeedback = postDict.get("deletedFeedback") if deletedFeedback: fb = Message(**deletedFeedback) for i, mro in enumerate(messages_received_list): if fb.objectId == mro.objectId: messages_received_list.pop(i) break session['messages_received_list'] =\ messages_received_list ############################################################# # MESSAGE SENT ################################## # need to check if this new message is an original message # or a reply to a feedback (the message sent by the patron)! # also may increment the message count! newMessage = postDict.get("newMessage") if newMessage: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] messages_sent_list =\ SESSION.get_messages_sent_list(session) messages_sent_ids =\ [ msg.objectId for msg in messages_sent_list ] m = Message(**newMessage) if m.objectId not in messages_sent_ids and\ m.message_type != FEEDBACK: messages_sent_list.insert(0, m) if 'message_count' in session: session['message_count'] =\ int(session['message_count']) + 1 # update an existing feedback if m.objectId in messages_received_ids and\ m.message_type == FEEDBACK: for i, mrl in enumerate(messages_received_list): if mrl.objectId == m.objectId: messages_received_list.pop(i) messages_received_list.insert(i, m) break session['messages_received_list'] =\ messages_received_list session['messages_sent_list'] = messages_sent_list ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! pendingEmployee = postDict.get("pendingEmployee") if pendingEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] employees_pending_ids =\ [ emp.objectId for emp in employees_pending_list ] e = Employee(**pendingEmployee) if e.objectId not in employees_pending_ids and\ e.objectId not in employees_approved_ids: employees_pending_list.insert(0, e) session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# approvedEmployee = postDict.get("approvedEmployee") if approvedEmployee: emp = Employee(**approvedEmployee) # first check if the employee is in the pending list # if not then check if it is already approved for i, emp_pending in\ enumerate(employees_pending_list): if emp.objectId == emp_pending.objectId: emp = employees_pending_list.pop(i) emp.status = APPROVED employees_approved_list.insert(0, emp) break session['employees_pending_list'] =\ employees_pending_list session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES NEW (straight to approved) ################# newEmployee = postDict.get("newEmployee") if newEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] emp = Employee(**newEmployee) if emp.objectId not in employees_approved_ids: employees_approved_list.insert(0, emp) session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! deletedEmployee = postDict.get("deletedEmployee") if deletedEmployee: emp = Employee(**deletedEmployee) # check in approved emps for i, cop in enumerate(employees_approved_list): if cop.objectId == emp.objectId: employees_approved_list.pop(i) break # check in pending emps for i, cop in enumerate(employees_pending_list): if cop.objectId == emp.objectId: employees_pending_list.pop(i) break session['employees_approved_list'] =\ employees_approved_list session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEE UPDATED PUNCHES updatedEmployeePunch = postDict.get("updatedEmployeePunch") if updatedEmployeePunch: u_emp = Employee(**updatedEmployeePunch) for emp in employees_approved_list: if u_emp.objectId == emp.objectId: emp.set("lifetime_punches", u_emp.lifetime_punches) break session['employees_approved_list'] =\ employees_approved_list ############################################################# # REDEMPTIONS PENDING ### Only added to cache if it has the store_location_id as ### active_store_location_id pendingRedemption = postDict.get("pendingRedemption") if pendingRedemption: rr = RedeemReward(**pendingRedemption) # store_location_id can be null for backwards compat if not rr.store_location_id or rr.store_location_id ==\ session.get('active_store_location_id'): redemptions_pending_ids =\ [ red.objectId for red in redemptions_pending ] redemptions_past_ids =\ [ red.objectId for red in redemptions_past ] # need to check here if the redemption is new because # the dashboard that validated it will also receive # the validated redemption back. if rr.objectId not in redemptions_past_ids and\ rr.objectId not in redemptions_pending_ids: redemptions_pending.insert(0, rr) session['redemptions_pending'] =\ redemptions_pending ############################################################# # REDEMPTIONS APPROVED (pending to history) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id approvedRedemption = postDict.get("approvedRedemption") if approvedRedemption: redemp = RedeemReward(**approvedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: r = redemptions_pending.pop(i) r.is_redeemed = True r.updatedAt = redemp.updatedAt redemptions_past.insert(0, r) break # if not then check if it is in the history already # the above shouldn't happen! session['redemptions_pending'] =\ redemptions_pending session['redemptions_past'] =\ redemptions_past ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id deletedRedemption = postDict.get("deletedRedemption") if deletedRedemption: redemp = RedeemReward(**deletedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: redemptions_pending.pop(i) break session['redemptions_pending'] =\ redemptions_pending ############################################################# # STORE UPDATED ############################## updatedStore = postDict.get("updatedStore") if updatedStore: store = Store(**updatedStore) # have to add the image url manually store.thumbnail_image_url = updatedStore.get("thumbnail_image_url") store.cover_image_url = updatedStore.get("cover_image_url") # below here for backwards compat store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreThumbnailName = postDict.get("updatedStoreThumbnailName") if updatedStoreThumbnailName: store = session['store'] store.thumbnail_image = updatedStoreThumbnailName store.thumbnail_image_url = postDict.get("updatedStoreThumbnailUrl") # below here for backwards compat store.store_avatar = store.thumbnail_image store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreCoverName = postDict.get("updatedStoreCoverName") if updatedStoreCoverName: store = session['store'] store.cover_image = updatedStoreCoverName store.cover_image_url = postDict.get("updatedStoreCoverUrl") session['store'] = store # this is in the settings tab in the dashboard but the field # is in the Store class updatedPunchesFacebook_int =\ postDict.get("updatedPunchesFacebook_int") if updatedPunchesFacebook_int: store = session['store'] store.punches_facebook = int(updatedPunchesFacebook_int) session['store'] = store ############################################################# # STORE LOCATION UPDATED ############################## ### Note that this is also being used to insert new StoreLocations updatedStoreLocation = postDict.get("updatedStoreLocation") if updatedStoreLocation: store_location = StoreLocation(**updatedStoreLocation) session['store_locations'][store_location.objectId] =\ store_location try: # also update the store_timezone session['store_timezone'] =\ pytz.timezone(store_location.get('store_timezone')) except Exception: # assign a default timezone session['store_timezone'] =\ pytz.timezone(TIME_ZONE) ############################################################# # ACCOUNT UPDATED ############################## updatedAccount = postDict.get("updatedAccount") if updatedAccount: updatedAccountObject = Account(**updatedAccount) # need to make sure that these are the same accounts! if session['account'].objectId ==\ updatedAccountObject.objectId: session['account'] = updatedAccountObject ############################################################# # SUBSCRIPTION UPDATED ############################## updatedSubscription =\ postDict.get("updatedSubscription") if updatedSubscription: subscription = Subscription(**updatedSubscription) store = session["store"] store.set('subscription', subscription) store.set('Subscription', subscription.objectId) session['subscription'] = subscription session['store'] = store ############################################################# # SETTINGS UPDATED ############################## updatedSettings = postDict.get("updatedSettings") if updatedSettings: settings = Settings(**updatedSettings) store = session["store"] store.set('settings', settings) store.set("Settings", settings.objectId) session['settings'] = settings session['store'] = store ############################################################# # REWARDS NEW ############################## newReward = postDict.get("newReward") if newReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [ r['reward_id'] for r in rewards ] if newReward['reward_id'] not in rewards_ids: rewards.append(newReward) store.rewards = rewards session['store'] = store ############################################################# # REWARDS UPDATED ############################## updatedReward = postDict.get('updatedReward') if updatedReward: store = session['store'] mod_rewards = store.get("rewards") for i, mreward in enumerate(mod_rewards): # [{"reward_name":"Free bottle of wine", # "description":"Must be under $25 in value", # "punches":10,"redemption_count":0,reward_id:0},] if updatedReward['reward_id']==mreward['reward_id']: if updatedReward.has_key("redemption_count"): mod_rewards[i]['redemption_count'] =\ updatedReward['redemption_count'] if updatedReward.has_key("reward_name"): mod_rewards[i]['reward_name'] =\ updatedReward['reward_name'] if updatedReward.has_key("punches"): mod_rewards[i]['punches'] =\ updatedReward['punches'] if updatedReward.has_key("description"): mod_rewards[i]['description'] =\ updatedReward['description'] break store.rewards = mod_rewards session['store'] = store ############################################################# # REWARDS DELETED ############################## deletedReward = postDict.get("deletedReward") if deletedReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [ r['reward_id'] for r in rewards ] if deletedReward['reward_id'] in rewards_ids: for i, r in enumerate(rewards): if r['reward_id'] == deletedReward['reward_id']: rewards.pop(i) break store.rewards = rewards session['store'] = store ############################################################# # PATRONSTORE_COUNT ################################## patronStore_int = postDict.get('patronStore_int') if patronStore_int: patronStore_int = int(patronStore_int) session['patronStore_count'] = patronStore_int
def processCometReceivedDict(session, postDict): employees_pending_list =\ SESSION.get_employees_pending_list(session) employees_approved_list =\ SESSION.get_employees_approved_list(session) messages_received_list =\ SESSION.get_messages_received_list(session) redemptions_pending =\ SESSION.get_redemptions_pending(session) redemptions_past =\ SESSION.get_redemptions_past(session) ############################################################# # FEEDBACKS_UNREAD ################################## newFeedback = postDict.get('newFeedback') if newFeedback: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] m = Message(**newFeedback) if m.objectId not in messages_received_ids: messages_received_list.insert(0, m) session['messages_received_list'] =\ messages_received_list ############################################################# # FEEDBACK DELETED ################################## deletedFeedback = postDict.get("deletedFeedback") if deletedFeedback: fb = Message(**deletedFeedback) for i, mro in enumerate(messages_received_list): if fb.objectId == mro.objectId: messages_received_list.pop(i) break session['messages_received_list'] =\ messages_received_list ############################################################# # MESSAGE SENT ################################## # need to check if this new message is an original message # or a reply to a feedback (the message sent by the patron)! # also may increment the message count! newMessage = postDict.get("newMessage") if newMessage: messages_received_ids =\ [ fb.objectId for fb in messages_received_list ] messages_sent_list =\ SESSION.get_messages_sent_list(session) messages_sent_ids =\ [ msg.objectId for msg in messages_sent_list ] m = Message(**newMessage) if m.objectId not in messages_sent_ids and\ m.message_type != FEEDBACK: messages_sent_list.insert(0, m) if 'message_count' in session: session['message_count'] =\ int(session['message_count']) + 1 # update an existing feedback if m.objectId in messages_received_ids and\ m.message_type == FEEDBACK: for i, mrl in enumerate(messages_received_list): if mrl.objectId == m.objectId: messages_received_list.pop(i) messages_received_list.insert(i, m) break session['messages_received_list'] =\ messages_received_list session['messages_sent_list'] = messages_sent_list ############################################################# # EMPLOYEES_PENDING ################################## # must also check if employee is already approved! pendingEmployee = postDict.get("pendingEmployee") if pendingEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] employees_pending_ids =\ [ emp.objectId for emp in employees_pending_list ] e = Employee(**pendingEmployee) if e.objectId not in employees_pending_ids and\ e.objectId not in employees_approved_ids: employees_pending_list.insert(0, e) session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEES APPROVED (pending to approved) ################# approvedEmployee = postDict.get("approvedEmployee") if approvedEmployee: emp = Employee(**approvedEmployee) # first check if the employee is in the pending list # if not then check if it is already approved for i, emp_pending in\ enumerate(employees_pending_list): if emp.objectId == emp_pending.objectId: emp = employees_pending_list.pop(i) emp.status = APPROVED employees_approved_list.insert(0, emp) break session['employees_pending_list'] =\ employees_pending_list session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES NEW (straight to approved) ################# newEmployee = postDict.get("newEmployee") if newEmployee: employees_approved_ids =\ [ emp.objectId for emp in employees_approved_list ] emp = Employee(**newEmployee) if emp.objectId not in employees_approved_ids: employees_approved_list.insert(0, emp) session['employees_approved_list'] =\ employees_approved_list ############################################################# # EMPLOYEES DELETED/DENIED/REJECTED (pending/approved to pop)! deletedEmployee = postDict.get("deletedEmployee") if deletedEmployee: emp = Employee(**deletedEmployee) # check in approved emps for i, cop in enumerate(employees_approved_list): if cop.objectId == emp.objectId: employees_approved_list.pop(i) break # check in pending emps for i, cop in enumerate(employees_pending_list): if cop.objectId == emp.objectId: employees_pending_list.pop(i) break session['employees_approved_list'] =\ employees_approved_list session['employees_pending_list'] =\ employees_pending_list ############################################################# # EMPLOYEE UPDATED PUNCHES updatedEmployeePunch = postDict.get("updatedEmployeePunch") if updatedEmployeePunch: u_emp = Employee(**updatedEmployeePunch) for emp in employees_approved_list: if u_emp.objectId == emp.objectId: emp.set("lifetime_punches", u_emp.lifetime_punches) break session['employees_approved_list'] =\ employees_approved_list ############################################################# # REDEMPTIONS PENDING ### Only added to cache if it has the store_location_id as ### active_store_location_id pendingRedemption = postDict.get("pendingRedemption") if pendingRedemption: rr = RedeemReward(**pendingRedemption) # store_location_id can be null for backwards compat if not rr.store_location_id or rr.store_location_id ==\ session.get('active_store_location_id'): redemptions_pending_ids =\ [ red.objectId for red in redemptions_pending ] redemptions_past_ids =\ [ red.objectId for red in redemptions_past ] # need to check here if the redemption is new because # the dashboard that validated it will also receive # the validated redemption back. if rr.objectId not in redemptions_past_ids and\ rr.objectId not in redemptions_pending_ids: redemptions_pending.insert(0, rr) session['redemptions_pending'] =\ redemptions_pending ############################################################# # REDEMPTIONS APPROVED (pending to history) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id approvedRedemption = postDict.get("approvedRedemption") if approvedRedemption: redemp = RedeemReward(**approvedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: r = redemptions_pending.pop(i) r.is_redeemed = True r.updatedAt = redemp.updatedAt redemptions_past.insert(0, r) break # if not then check if it is in the history already # the above shouldn't happen! session['redemptions_pending'] =\ redemptions_pending session['redemptions_past'] =\ redemptions_past ############################################################# # REDEMPTIONS DELETED ############################## # remove from pending (should not be in history!) # Save cpu by skipping those that do not have the same # store_location_id as active_store_location_id deletedRedemption = postDict.get("deletedRedemption") if deletedRedemption: redemp = RedeemReward(**deletedRedemption) # store_location_id can be null for backwards compat if not redemp.store_location_id or redemp.store_location_id ==\ session.get('active_store_location_id'): # check if redemp is still in pending for i, redem in enumerate(redemptions_pending): if redem.objectId == redemp.objectId: redemptions_pending.pop(i) break session['redemptions_pending'] =\ redemptions_pending ############################################################# # STORE UPDATED ############################## updatedStore = postDict.get("updatedStore") if updatedStore: store = Store(**updatedStore) # have to add the image url manually store.thumbnail_image_url = updatedStore.get("thumbnail_image_url") store.cover_image_url = updatedStore.get("cover_image_url") # below here for backwards compat store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreThumbnailName = postDict.get("updatedStoreThumbnailName") if updatedStoreThumbnailName: store = session['store'] store.thumbnail_image = updatedStoreThumbnailName store.thumbnail_image_url = postDict.get( "updatedStoreThumbnailUrl") # below here for backwards compat store.store_avatar = store.thumbnail_image store.store_avatar_url = store.thumbnail_image_url session['store'] = store updatedStoreCoverName = postDict.get("updatedStoreCoverName") if updatedStoreCoverName: store = session['store'] store.cover_image = updatedStoreCoverName store.cover_image_url = postDict.get("updatedStoreCoverUrl") session['store'] = store # this is in the settings tab in the dashboard but the field # is in the Store class updatedPunchesFacebook_int =\ postDict.get("updatedPunchesFacebook_int") if updatedPunchesFacebook_int: store = session['store'] store.punches_facebook = int(updatedPunchesFacebook_int) session['store'] = store ############################################################# # STORE LOCATION UPDATED ############################## ### Note that this is also being used to insert new StoreLocations updatedStoreLocation = postDict.get("updatedStoreLocation") if updatedStoreLocation: store_location = StoreLocation(**updatedStoreLocation) session['store_locations'][store_location.objectId] =\ store_location try: # also update the store_timezone session['store_timezone'] =\ pytz.timezone(store_location.get('store_timezone')) except Exception: # assign a default timezone session['store_timezone'] =\ pytz.timezone(TIME_ZONE) ############################################################# # ACCOUNT UPDATED ############################## updatedAccount = postDict.get("updatedAccount") if updatedAccount: updatedAccountObject = Account(**updatedAccount) # need to make sure that these are the same accounts! if session['account'].objectId ==\ updatedAccountObject.objectId: session['account'] = updatedAccountObject ############################################################# # SUBSCRIPTION UPDATED ############################## updatedSubscription =\ postDict.get("updatedSubscription") if updatedSubscription: subscription = Subscription(**updatedSubscription) store = session["store"] store.set('subscription', subscription) store.set('Subscription', subscription.objectId) session['subscription'] = subscription session['store'] = store ############################################################# # SETTINGS UPDATED ############################## updatedSettings = postDict.get("updatedSettings") if updatedSettings: settings = Settings(**updatedSettings) store = session["store"] store.set('settings', settings) store.set("Settings", settings.objectId) session['settings'] = settings session['store'] = store ############################################################# # REWARDS NEW ############################## newReward = postDict.get("newReward") if newReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [r['reward_id'] for r in rewards] if newReward['reward_id'] not in rewards_ids: rewards.append(newReward) store.rewards = rewards session['store'] = store ############################################################# # REWARDS UPDATED ############################## updatedReward = postDict.get('updatedReward') if updatedReward: store = session['store'] mod_rewards = store.get("rewards") for i, mreward in enumerate(mod_rewards): # [{"reward_name":"Free bottle of wine", # "description":"Must be under $25 in value", # "punches":10,"redemption_count":0,reward_id:0},] if updatedReward['reward_id'] == mreward['reward_id']: if updatedReward.has_key("redemption_count"): mod_rewards[i]['redemption_count'] =\ updatedReward['redemption_count'] if updatedReward.has_key("reward_name"): mod_rewards[i]['reward_name'] =\ updatedReward['reward_name'] if updatedReward.has_key("punches"): mod_rewards[i]['punches'] =\ updatedReward['punches'] if updatedReward.has_key("description"): mod_rewards[i]['description'] =\ updatedReward['description'] break store.rewards = mod_rewards session['store'] = store ############################################################# # REWARDS DELETED ############################## deletedReward = postDict.get("deletedReward") if deletedReward: store = session['store'] rewards = store.get("rewards") rewards_ids = [r['reward_id'] for r in rewards] if deletedReward['reward_id'] in rewards_ids: for i, r in enumerate(rewards): if r['reward_id'] == deletedReward['reward_id']: rewards.pop(i) break store.rewards = rewards session['store'] = store ############################################################# # PATRONSTORE_COUNT ################################## patronStore_int = postDict.get('patronStore_int') if patronStore_int: patronStore_int = int(patronStore_int) session['patronStore_count'] = patronStore_int