示例#1
0
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)
示例#2
0
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]))
示例#4
0
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)
示例#5
0
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)
示例#6
0
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,
        })
示例#7
0
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)
示例#9
0
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
示例#10
0
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)
示例#11
0
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)
示例#12
0
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
示例#13
0
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()]))
示例#14
0
 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())
示例#15
0
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)
示例#16
0
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))
示例#17
0
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)
示例#19
0
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)
示例#20
0
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)
示例#21
0
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)
示例#22
0
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())
示例#25
0
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)
示例#26
0
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)
示例#27
0
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)
示例#28
0
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)
示例#29
0
 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)
示例#30
0
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)