def _OrderPut(request, user, order): order_items = list(models.OrderItem.all().filter('order = ', order)) _SortOrderItemsWithSections(order_items) if order.state == 'new': what = 'Enter quantities for items.' submit_button_text = 'Submit this order' else: what = 'Update quantities if necessary.' submit_button_text = 'Submit changes' if order.order_sheet.HasLogistics(): submit_button_text += ' and proceed to delivery options' form_cls = forms.CaptainOrderForm if user.staff: form_cls = forms.OrderForm form = form_cls(data=request.POST or None, files=request.FILES or None, instance=order) # A little sketchy, but the best way to adjust HTML attributes of a field. form['notes'].field.widget.attrs['cols'] = 120 form['notes'].field.widget.attrs['rows'] = max( 5, len(form.instance.VisibleNotes().splitlines())) created_by_user = common.GetUser(request, order.last_editor)[0], template_dict = { 'form': form, 'notes_field': form['notes'], 'order': order, 'order_items': order_items, 'created_by_user': common.GetUser(request, order.created_by)[0], 'modified_by_user': common.GetUser(request, order.last_editor)[0], 'sales_tax_pct': SALES_TAX_RATE * 100., 'what_you_are_doing': what, 'show_instructions': True, 'submit_button_text': submit_button_text, } if not request.POST: logging.error("issue191log no post in _OrderPut") return None, template_dict errors = form.errors if not errors: try: order = form.save(commit=False) except ValueError, err: errors['__all__'] = unicode(err)
def SiteBudget(request): """List all Sites with a "Budget" view.""" user, _, staff = common.GetUser(request) if not staff: return http.HttpResponse(status=400) params = { 'export_csv': EXPORT_CSV, 'export_checkbox_prefix': POSTED_ID_PREFIX } query = models.NewSite.all() if staff and staff.program_selected: query.filter('program =', staff.program_selected) params['program'] = staff.program_selected # this 'q' param is just for testing if 'q' in request.GET: query.filter('search_prefixes = ', request.GET['q'].lower()) params['search'] = request.GET['q'] params['jurisdiction'] = request.GET.get('j') if params['jurisdiction']: query.filter('jurisdiction = ', params['jurisdiction']) entries = list(query) total = 0 for site in entries: total += site.Expenses() params.update({ 'entries': entries, 'num_entries': len(entries), 'user': user, 'total_expenses': total }) return common.Respond(request, 'site_budget', params)
def AddStandardKitOrder(request, prefix): user, _, _ = common.GetUser(request) skos = models.OrderSheet.all().filter('code = ', 'SDK').get() if not skos: logging.warn('can not find SDK order sheet') return http.HttpResponse( urlresolvers.reverse(AddStandardKitOrder, args=[prefix])) i = skos.item_set.get() if not i: logging.warn('can not find item for SDK order sheet') return http.HttpResponse( urlresolvers.reverse(AddStandardKitOrder, args=[prefix])) for site in models.NewSite.all().filter('program =', user.program_selected): if not site.number.startswith(prefix): logging.info('skipping site %r because wrong prefix %r', site.number, prefix) continue if site.order_set.filter('order_sheet = ', skos).count(): logging.info('skipping site %r because has SDK order', site.number) continue sko = models.Order(site=site, order_sheet=skos, state='Received') sko.put() oi = models.OrderItem(order=sko, item=i, quantity_float=1) oi.put() logging.info('created SDK order for site %r', site.number) sko.UpdateSubTotal() sko.put() return http.HttpResponse( urlresolvers.reverse(AddStandardKitOrder, args=[prefix]))
def OrderSheetEdit(request, order_sheet_id=None): """Create or edit a canned order.""" user, _, _ = common.GetUser(request) order_sheet = None if order_sheet_id: order_sheet = models.OrderSheet.get( db.Key.from_path(models.OrderSheet.kind(), int(order_sheet_id))) if order_sheet is None: return http.HttpResponseNotFound( 'No order_sheet exists with that key (%r)' % order_sheet_id) what = 'Changing existing Order Form' else: what = 'Adding new Order Form' form = forms.OrderSheetForm(data=request.POST or None, instance=order_sheet) if not request.POST: return common.Respond(request, 'order_sheet', { 'form': form, 'order_sheet': order_sheet, 'what_you_are_doing': what }) errors = form.errors if not errors: try: order_sheet = form.save(commit=False) except ValueError, err: errors['__all__'] = unicode(err)
def _SiteListInternal(request, site=None, new_order_form=None): """Request / -- show all canned orders.""" params = dict(map_width=MAP_WIDTH, map_height=MAP_HEIGHT) user, _, _ = common.GetUser(request) d = {'user': user} if site is not None: template = 'site_list_one' if new_order_form is None: site.new_order_form = forms.NewOrderForm(initial=dict( site=site.key())) else: site.new_order_form = new_order_form entries = [site] d['site_list_detail'] = True d['start_new_order_submit'] = START_NEW_ORDER_SUBMIT else: # TODO: can we remove this view? template = 'site_list_all' entries = list(models.NewSite.all()) entries.sort(key=lambda x: x.number) AnnotateSitesWithEditability(entries, user.captain, user.staff) d['entries'] = entries order_sheets = models.OrderSheet.all().order('name') d['order_sheets'] = order_sheets if params: d.update(params) return common.Respond(request, template, d)
def CaptainHome(request, captain_id=None): user, captain, staff = common.GetUser(request) if user is None: return http.HttpResponseRedirect('/') if captain_id is not None: captain = models.Captain.get_by_id(int(captain_id)) order_sheets = models.OrderSheet.all().order('name') sites = [] for sitecaptain in captain.sitecaptain_set: site = sitecaptain.site if site.program != common.DEFAULT_CAPTAIN_PROGRAM: continue site.new_order_form = forms.NewOrderForm(initial=dict(site=site.key())) sites.append(site) AnnotateSitesWithEditability(sites, captain, staff) captain_form = forms.CaptainContactForm(data=request.POST or None, instance=captain) return common.Respond( request, 'captain_home', { 'order_sheets': order_sheets, 'entries': sites, 'captain': captain, 'captain_form': captain_form, 'captain_contact_submit': 'Save changes to personal info', 'map_width': MAP_WIDTH, 'map_height': MAP_HEIGHT, 'site_list_detail': True, 'start_new_order_submit': START_NEW_ORDER_SUBMIT, })
def SiteList(request): """Request / show all Sites. Was return _EntryList(request, models.NewSite, 'site_list') but we need special handling for sitecaptains. """ user, captain, staff = common.GetUser(request) query = models.NewSite.all().order('number') if staff and staff.program_selected: query.filter('program =', staff.program_selected) entries = list(query) sitecaptains_by_site = {} # TODO: this is fetching too many - we only need those for the current # program for sc in models.SiteCaptain.all(): sitecaptains_by_site.setdefault(sc.site.key().id(), []).append(sc) for s in entries: k = s.key().id() if k in sitecaptains_by_site: s.sitecaptains = sitecaptains_by_site[k] d = { 'entries': entries, 'num_entries': len(entries), 'user': user, 'sitecaptains_by_site': sitecaptains_by_site } return common.Respond(request, 'site_list', d)
def SitesWithoutOrder(request, order_sheet_id): user, _, _ = common.GetUser(request) order_sheet = models.OrderSheet.get_by_id(int(order_sheet_id)) if order_sheet is None: return http.HttpResponseNotFound( 'No order_sheet exists with that key (%r)' % order_sheet_id) query = models.NewSite.all() query.filter('program =', user.program_selected) all_sites = list(query) orders = models.Order.all().filter('order_sheet =', order_sheet) orders.filter('state != ', 'new') orders.filter('program =', user.program_selected) order_sites = [o.site for o in orders] sites_without_order = [s for s in all_sites if s not in order_sites] sites_without_order.sort(key=lambda s: s.number) staff = models.Staff.all().order('name') template_dict = { 'sites': sites_without_order, 'num_sites_without_order': len(sites_without_order), 'num_sites': len(all_sites), 'staff': staff, 'user': user, 'order_sheet': order_sheet, 'EMAIL_LOG': common.EMAIL_LOG, 'EMAIL_LOG_LINK': common.EMAIL_LOG_LINK, } return common.Respond(request, 'sites_without_order', template_dict)
def CaptainExport(request): """Export all Captains as CSV.""" user, _, _ = common.GetUser(request) captains = list(models.Captain.all().order('name')) response = http.HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=room_captains.csv' writer = csv.writer(response) writer.writerow([ 'Captain ID', 'Name', 'Email', 'Preferred Phone', 'Backup Phone', 'Sites', 'Type', 'T-Shirt', 'Last Welcome', 'Notes' ]) for c in captains: sc = list(c.sitecaptain_set) sites = '+'.join(set(s.site.number for s in sc)) type = '+'.join(set(s.type for s in sc)) writer.writerow([ c.key().id(), c.name, c.email, c.phone1, c.phone2, sites, type, c.tshirt_size, c.last_welcome, c.notes, ]) return response
def OrderPreview(request, site_id=None): user, _, _ = common.GetUser(request) if user is None: return http.HttpResponseRedirect(users.CreateLoginURL(request.path)) site = models.NewSite.get_by_id(int(site_id)) existing_orders = {} query = site.Orders.Items() for order in query: if order.order_sheet.code not in existing_orders: existing_orders[order.order_sheet.code] = [] existing_orders[order.order_sheet.code].append(order) order_sheets = models.OrderSheet.all().order('name') order_sheets = [o for o in order_sheets if o.visibility != 'Staff Only'] for os in order_sheets: order_items = [models.OrderItem(item=i) for i in os.item_set] _SortOrderItemsWithSections(order_items) os.sorted_items = order_items[:] os.num_existing_orders = 0 if os.code in existing_orders: os.existing_orders = existing_orders[os.code] os.num_existing_orders = len(existing_orders[os.code]) t = {'order_sheets': order_sheets, 'site': site} return common.Respond(request, 'order_preview', t)
def _EntryList(request, model_cls, template, params=None, query=None): """Generic method to perform a list view. Template should iterate over a list called 'entries'. Sorts entries on their 'name' attribute (which they must have). Args: request: the request object model_cls: the class of model, like models.Captain template: name of template file, like 'captain_list' params: dict of more template parameters query: db.Query object to use, if not model_cls.all() """ user, captain, staff = common.GetUser(request) if query is None: query = model_cls.all() entries = list(query) entries.sort(key=lambda x: x.name) d = { 'entries': entries, 'num_entries': len(entries), 'user': user, 'cls': model_cls, 'model_cls_name': model_cls.__name__ } if params: d.update(params) return common.Respond(request, template, d)
def SiteBudgetExport(request): """Export Site budget rows as CSV.""" user, _, _ = common.GetUser(request) if request.POST['submit'] == EXPORT_CSV: response = http.HttpResponse(mimetype='text/csv') response['Content-Disposition'] = ( 'attachment; filename=%s_site_budget.csv' % user.email()) _SiteBudgetExportInternal(response, request.POST) return response
def SiteJump(request): user, _, _ = common.GetUser(request) d = {'user': user} number = request.GET['number'] site = models.NewSite.all().filter('number = ', number).get() if site is None: return http.HttpResponseRedirect(urlresolvers.reverse(StaffHome)) else: return http.HttpResponseRedirect( urlresolvers.reverse(views.SiteView, args=[site.key().id()]))
def New(cls, request, site_id): """Create an entity. GET shows a blank form, POST processes it.""" user, user_captain, staff = common.GetUser(request) site = models.NewSite.get_by_id(int(site_id)) if user_captain: instance = cls.model(site=site, captain=user_captain) else: instance = cls.model(site=site) instance.put() return cls.Edit(request, instance.key().id())
def OrderEdit(request, order_id): """Create or edit a order. GET shows a blank form, POST processes it.""" user, _, _ = common.GetUser(request) if user is None: return http.HttpResponseRedirect(users.CreateLoginURL(request.path)) redirect, template_dict = _OrderEditInternal(request, user, order_id) if redirect is not None: return redirect else: return common.Respond(request, 'order', template_dict)
def SelectProgram(request, program=None): user, _, staff = common.GetUser(request) if program is None: what_you_are_doing = "Select a Program to work on" return common.Respond(request, 'select_program', locals()) if program not in common.PROGRAMS: return http.HttpResponseError('program %s not in PROGRAMS' % program) staff.program_selected = program staff.put() return http.HttpResponseRedirect(urlresolvers.reverse(StaffHome))
def OrderItemName(request): user, _, _ = common.GetUser(request) if user is None: return http.HttpResponse(status=400) order_item_id = int(request.POST['id']) order_item = models.OrderItem.get_by_id(order_item_id) if order_item is None: return http.HttpResponse(status=400) order_item.name = request.POST['value'] order_item.put() return http.HttpResponse(order_item.name)
def ScoreboardOrders(request): user, _, _ = common.GetUser(request) activity = [] activity_rows = [ ('All Orders', models.Order.all().filter('program =', user.program_selected), urlresolvers.reverse(order.OrderList)), ('Check Requests', models.CheckRequest.all().filter('program =', user.program_selected), urlresolvers.reverse(views.CheckRequestList)), ('Vendor Receipts', models.VendorReceipt.all().filter('program =', user.program_selected), urlresolvers.reverse(views.VendorReceiptList)), ('In-kind Donations', models.InKindDonation.all().filter('program =', user.program_selected), urlresolvers.reverse(views.InKindDonationList)), ] order_sheets = models.OrderSheet.all().order('name') order_sheets = [o for o in order_sheets if o.visibility != 'Staff Only'] for os in order_sheets: query = models.Order.all().filter('program =', user.program_selected) query.filter('order_sheet =', os) activity_rows.append(('Form: %s' % os.name[0:20], query, urlresolvers.reverse(order.OrderList, args=[os.key().id()]))) now = datetime.datetime.now() one = datetime.timedelta(days=1) for name, query, link in activity_rows: items = filter(lambda i: 'ZZZ' not in i.site.number, query) total = sum(i.Total() for i in items) sites = len(set(i.site.number for i in items)) editors = len(set(i.last_editor for i in items)) totals_by_state = {} for i in items: totals_by_state[i.state] = totals_by_state.get(i.state, 0) + 1 received_orders = [ i for i in items if i.state in ('Received', 'submitted') ] recent = len([s for s in received_orders if now - s.modified < one]) logging.info('got activity row: %s', name) activity.append( (name, link, totals_by_state.get('Received', 0) + totals_by_state.get('submitted', 0), recent, total, sites, editors, totals_by_state.get('Deleted', 0) + totals_by_state.get('new', 0), totals_by_state.get('new', 0), totals_by_state.get('Being Filled', 0), totals_by_state.get('Reconciled', 0))) d = locals() return common.Respond(request, 'scoreboard_orders', d)
def OrderExport(request): """Export orders as CSV.""" user, _, _ = common.GetUser(request) if request.POST['submit'] == views.EXPORT_CSV: response = http.HttpResponse(mimetype='text/csv') response['Content-Disposition'] = ( 'attachment; filename=%s_orders.csv' % user.email()) _OrderExportInternal(response, request.POST) return response elif request.POST['submit'] == FULFILL_MULTIPLE: order_ids = views.PostedIds(request.POST) order_sheet_id = request.POST.get('order_sheet_id') d = _OrderFulfillInternal(order_ids, order_sheet_id, mode='fulfill') return common.Respond(request, 'order_fulfill', d)
def StaffHome(request): user, _, staff = common.GetUser(request) if not staff.program_selected: return http.HttpResponseRedirect(urlresolvers.reverse(SelectProgram)) order_sheets = list(models.OrderSheet.all()) order_sheets.sort(key=lambda x: x.name) jurisdictions = list(models.Jurisdiction.all()) jurisdictions.sort(key=lambda x: x.name) d = { 'order_sheets': order_sheets, 'test_site_number': TEST_SITE_NUMBER, 'jurisdictions': jurisdictions, } return common.Respond(request, 'staff_home', d)
def SiteExpenseState(request, item_cls, item_id): """Updates a site expense's state field.""" user, captain, staff = common.GetUser(request) if not staff: return http.HttpResponse(status=400) if not request.POST: return http.HttpResponse(status=400) cls = SITE_EXPENSE_TYPES[item_cls] modl = cls.get_by_id(int(item_id)) if not modl: return http.HttpResponse(status=400) value = request.POST['value'] modl.state = value modl.put() return http.HttpResponse(value, status=200)
def _Autocomplete(request, model_class, program_filter=False): prefix = str(request.GET['term']).lower() items = model_class.all() items.filter('search_prefixes = ', prefix) if program_filter: user, _, _ = common.GetUser(request) items.filter('program =', user.program_selected) matches = {} for c in items: label = c.Label() matches[label] = c.key().id() response = http.HttpResponse(mimetype='application/json') response.write(json.dumps(matches)) return response
def _ScoreboardUsers(user_cls, request): user, _, _ = common.GetUser(request) user_activity = [] welcomes = user_cls.all().filter('last_welcome != ', None).order('-last_welcome').fetch(20) for c in welcomes: u = users.User(c.email) equery = models.Order.all().filter( 'state IN ', ('Received', 'submitted', 'Being Filled')) equery.filter('program =', user.program_selected) equery.filter('created_by =', u) orders = list(equery) recent_orders = filter(lambda o: o.created > c.last_welcome, orders) user_activity.append((c, len(orders), len(recent_orders))) return user_activity
def Scoreboard(request): user, _, _ = common.GetUser(request) num_captains = models.Captain.all().count() num_captains_active = models.Captain.all().filter('last_welcome != ', None).count() pct_captains_active = num_captains_active * 100.0 / num_captains num_captains_with_tshirt = models.Captain.all().filter( 'tshirt_size != ', None).count() query = models.NewSite.all().order('number') query.filter('program =', user.program_selected) sites = list(query) num_sites = len(sites) total_site_budget = sum(s.budget for s in sites if s.budget) return common.Respond(request, 'scoreboard', locals())
def SiteAnnouncement(request, site_id): """Updates a site's announcement fields.""" user, captain, staff = common.GetUser(request) if not staff: return http.HttpResponse(status=400) if not request.POST: return http.HttpResponse(status=400) site = models.NewSite.get_by_id(int(site_id)) if not site: return http.HttpResponse(status=400) field = request.POST['id'] value = request.POST['value'] setattr(site, field, value) site.put() return http.HttpResponse(value, status=200)
def _SetField(model_cls, cast, request, id): user, captain, staff = common.GetUser(request) if not staff: return http.HttpResponse(status=400) if not request.POST: return http.HttpResponse(status=400) obj = model_cls.get_by_id(int(id)) if not obj: return http.HttpResponse(status=400) field = request.POST['id'] if not field: return http.HttpResponse(status=400) value = request.POST['value'] if cast is not None: value = cast(value) setattr(obj, field, value) obj.put() return http.HttpResponse(value, status=200)
def ChangeOrder(request, order_id, input_sanitizer, output_filter=None): """Changes an order field based on POST data from jeditable.""" user, captain, staff = common.GetUser(request) if not staff: return http.HttpResponse(status=400) if not request.POST: return http.HttpResponse(status=400) order = models.Order.get_by_id(int(order_id)) if not order: return http.HttpResponse(status=400) field = request.POST['id'] value = input_sanitizer(request.POST['value']) logging.info(" setattr(order, %s, %r)", field, value) setattr(order, field, value) order.put() if output_filter is not None: value = output_filter(value) return http.HttpResponse(value, status=200)
def CaptainEdit(request, captain_id=None): """Create or edit a Captain.""" user, user_captain, staff = common.GetUser(request) captain = None if captain_id: captain = models.Captain.get_by_id(int(captain_id)) if captain is None: return http.HttpResponseNotFound( 'No captain exists with that key (%r)' % captain_id) what = 'Changing existing Captain' else: what = 'Adding new Captain' if staff: form_class = forms.CaptainForm elif user_captain and user_captain == captain: form_class = forms.CaptainContactForm else: template_dict = { 'what_you_are_doing': 'Not permitted to edit this Captain.' } return common.Respond(request, 'captain', template_dict) form = form_class(data=None, instance=captain) template_dict = { 'form': form, 'captain': captain, 'what_you_are_doing': what } if request.POST: form = form_class(data=request.POST or None, instance=captain) template_dict['form'] = form if _TryToSaveForm(form): if staff: return http.HttpResponseRedirect( urlresolvers.reverse(CaptainList)) else: return http.HttpResponseRedirect( urlresolvers.reverse(CaptainHome)) return common.Respond(request, 'captain', template_dict)
def List(cls, request, site_id=None): """Show all.""" query = cls.model.all().filter('state !=', 'new') params = { 'which_site': 'All', 'expense_type': cls.readable, 'table_template': cls.template_base + '_table.html' } if site_id is not None: site = models.NewSite.get_by_id(int(site_id)) query.filter('site = ', site) params['which_site'] = 'Site ' + site.number else: user, _, _ = common.GetUser(request) query.filter('program =', user.program_selected) return _EntryList(request, cls.model, 'site_expense_list', params=params, query=query)
def OrderNew(request, site_id=None, order_sheet_code=None): """Create a new order and forward to the edit screen.""" user, _, _ = common.GetUser(request) if user is None: return http.HttpResponseRedirect(users.CreateLoginURL(request.path)) site = models.NewSite.get_by_id(int(site_id)) order_sheet = models.OrderSheet.all().filter('code = ', order_sheet_code).get() # TODO: error if order_sheet is None order = models.Order(site=site, order_sheet=order_sheet, state='new') order.put() for item in order.order_sheet.item_set: order_item = models.OrderItem(order=order, item=item) order_item.put() redirect, template_dict = _OrderPut(request, user, order) if redirect is not None: return redirect else: return common.Respond(request, 'order', template_dict)