Exemple #1
0
def list_users(request, company):
    """ show a list of users and their pins """
    c = get_object_or_404(Company, url_name=company)

    # check permission
    if not has_permission(request.user, c, 'user', 'view'):
        return no_permission_view(request, c, _("You have no permission to view users' settings."))

    # this company's permissions
    permissions = Permission.objects.filter(company=c)

    # show waiting and canceled invites
    actions = Action.objects.filter(company=c, type=g.ACTION_INVITATION)

    # do some nice formatting on the actions
    for a in actions:
        a.sender = str(BlocklogicUser.objects.get(email=a.sender))

    context = {
        'company': c,

        'permissions': permissions,
        'permission_groups': g.PERMISSION_GROUPS,

        'actions': actions,

        'pin_length': g.PIN_LENGTH,

        'title': _("Users"),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
    }

    return render(request, 'pos/manage/users.html', context)
Exemple #2
0
def add_register(request, company):
    # add a new register
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be manager
    if not has_permission(request.user, c, 'register', 'edit'):
        return no_permission_view(request, c, _("You have no permission to add printers."))

    context = {
        'add': True,
        'company': c,
        'title': _("Add printer"),
        'site_title': g.MISC['site_title'],
        'date_format_js': get_date_format(request.user, c, 'js')
    }

    if request.method == 'POST':
        # submit data
        form = RegisterForm(request.POST)

        if form.is_valid():
            register = form.save(False)
            register.company = c
            register.created_by = request.user
            register.save()

            return redirect('pos:list_registers', company=c.url_name)
    else:
        form = RegisterForm()
        form.user = request.user
        form.company = c

    context['form'] = form

    return render(request, 'pos/manage/register.html', context)
Exemple #3
0
def manage_documents(request, company, page):
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'stock', 'view'):
        return no_permission_view(request, c, _("You have no permission to view stock."))

    documents = Document.objects.filter(company=c).order_by('-number')

    paginator = Paginator(documents, g.MISC['documents_per_page'])

    if page:
        documents = paginator.page(page)
    else:
        documents = paginator.page(1)

    context = {
        'managing': 'documents',
        'company': c,
        'documents': documents,
        # 'searched': searched,
        # 'filter_form': form,
        'title': _("Stock"),
        'next_url': reverse('pos:manage_documents', args=[c.url_name, int(page)+1]),
        'prev_url': reverse('pos:manage_documents', args=[c.url_name, int(page)-1]),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'date_format_js': get_date_format(request.user, c, 'js'),
    }

    return render(request, 'pos/manage/manage_documents.html', context)
Exemple #4
0
def add_contact(request, company):
    # add a new contact
    c = get_object_or_404(Company, url_name=company)
    
    # check permissions: needs to be manager
    if not has_permission(request.user, c, 'contact', 'edit'):
        return no_permission_view(request, c, _("You have no permission to add contacts."))

    t = request.GET.get('type')
    if not t:
        t = 'Individual'  # the default

    context = {
        'add': True,
        'type': t,
        'company': c,
        'title': _("Add contact"),
        'site_title': g.MISC['site_title'],
        'date_format_js': get_date_format(request.user, c, 'js')
    }

    if request.method == 'POST':
        # submit data
        form = ContactForm(request.POST)
        form.user = request.user
        form.company = c

        if form.is_valid():
            # create a new Contact
            contact = Contact(
                type=form.cleaned_data.get('type'),
                company_name=form.cleaned_data.get('company_name'),
                first_name=form.cleaned_data.get('first_name'),
                last_name=form.cleaned_data.get('last_name'),
                sex=form.cleaned_data.get('sex'),
                street_address=form.cleaned_data.get('street_address'),
                postcode=form.cleaned_data.get('postcode'),
                city=form.cleaned_data.get('city'),
                state=form.cleaned_data.get('state'),
                country=form.cleaned_data.get('country'),
                email=form.cleaned_data.get('email'),
                phone=form.cleaned_data.get('phone'),
                vat=form.cleaned_data.get('vat'),
                date_of_birth=form.cleaned_data.get('date_of_birth'),
                
                created_by=request.user,
                company=c
            )
            contact.save()

            return redirect('pos:list_contacts', company=c.url_name)
    else:
        form = ContactForm(initial={'type': t, 'country': c.country})
        form.user = request.user
        form.company = c

    context['form'] = form
    
    return render(request, 'pos/manage/contact.html', context)
Exemple #5
0
def list_contacts(request, company):
    c = get_object_or_404(Company, url_name=company)
    
    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'contact', 'view'):
        return no_permission_view(request, c, _("You have no permission to view contacts."))

    l = request.GET.get('letter')
    results_display = False  # true if there was something in the search form

    # show the filter form
    if request.method == 'POST':
        contacts = Contact.objects.all()
        form = ContactFilterForm(request.POST)
        results_display = True

        if form.is_valid():
            # filter by whatever is in the form
            if form.cleaned_data['type'] == 'Individual':
                contacts = contacts.filter(type='Individual')
                if 'name' in form.cleaned_data:  # search by first and last name
                    first_names = contacts.filter(first_name__icontains=form.cleaned_data['name'])
                    last_names = contacts.filter(last_name__icontains=form.cleaned_data['name'])
                    contacts = (first_names | last_names).distinct()
            else:
                contacts = contacts.filter(type='Company')
                if 'name' in form.cleaned_data:  # search by company name
                    contacts = contacts.filter(company_name__icontains=form.cleaned_data['name'])
    else:
        form = ContactFilterForm()

        if l:
            if l == '*':
                # get all contacts that don't begin with any letter of the alphabet
                contacts = Contact.objects.filter(company=c,
                                                  company_name__iregex=r'^[^' + g.ALPHABETS[get_language()] + '].*') | \
                           Contact.objects.filter(company=c,
                                                  first_name__iregex=r'^[^' + g.ALPHABETS[get_language()] + '].*')

            else:
                # get contacts beginning with the selected letter
                contacts = Contact.objects.filter(company=c, company_name__istartswith=l) | \
                           Contact.objects.filter(company=c, first_name__istartswith=l)
        else:
            contacts = Contact.objects.none()
        
    context = {
        'company': c,
        'letter': l,
        'contacts': contacts,
        'filter_form': form,
        'results_display': results_display,
        'title': _("Contacts"),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'alphabet': g.ALPHABETS[get_language()],
    }

    return render(request, 'pos/manage/contacts.html', context)
Exemple #6
0
def edit_contact(request, company, contact_id):
    # edit an existing contact
    c = get_object_or_404(Company, url_name=company)
    
    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'contact', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit contacts."))
    
    context = {
        'company': c,
        'contact_id': contact_id,
        'title': _("Edit contact"),
        'site_title': g.MISC['site_title'],
        'date_format_js': get_date_format(request.user, c, 'js'),
    }
    
    # get contact
    contact = get_object_or_404(Contact, id=contact_id)
        
    # check if contact actually belongs to the given company
    if contact.company != c:
        raise Http404
        
    if request.method == 'POST':
        # submit data
        form = ContactForm(request.POST)
        form.user = request.user
        form.company = c

        if form.is_valid():
            contact.type = form.cleaned_data.get('type')
            contact.company_name = form.cleaned_data.get('company_name')
            contact.first_name = form.cleaned_data.get('first_name')
            contact.last_name = form.cleaned_data.get('last_name')
            contact.sex = form.cleaned_data.get('sex')
            contact.date_of_birth = form.cleaned_data.get('date_of_birth')
            contact.street_address = form.cleaned_data.get('street_address')
            contact.postcode = form.cleaned_data.get('postcode')
            contact.city = form.cleaned_data.get('city')
            contact.state = form.cleaned_data.get('state')
            contact.country = form.cleaned_data.get('country')
            contact.email = form.cleaned_data.get('email')
            contact.phone = form.cleaned_data.get('phone')
            contact.vat = form.cleaned_data.get('vat')
            contact.save()
            
            return redirect('pos:list_contacts', company=c.url_name)
    else:
        initial = contact_to_dict(request.user, c, contact)
        form = ContactForm(initial=initial)
        form.user = request.user
        form.company = c

    context['form'] = form
    context['type'] = contact.type
    
    return render(request, 'pos/manage/contact.html', context)
Exemple #7
0
def get_mobile_config(request, company_id):
    try:
        c = Company.objects.get(id=company_id)
    except Company.DoesNotExist:
        return JsonError(_("Company does not exist"))

    # permissions
    if not has_permission(request.user, c, 'config', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit system configuration."))

    return JsonOk(extra=company_config_to_dict(request.user, c))
Exemple #8
0
def products(request, company):
    c = get_object_or_404(Company, url_name=company)
    
    # needs to be at least guest to view products
    if not has_permission(request.user, c, 'product', 'view'):
        return no_permission_view(request, c, _("You have no permission to view products."))

    # if there are no taxes defined, don't show anything
    if Tax.objects.filter(company=c).count() == 0:
        return error(request, c, _("There are no taxes defined. Please go to tax management and define them."))

    # if there are no categories defined, throw an error
    if Category.objects.filter(company=c).count() == 0:
        return error(request, c, _("There are no categories defined, please go to category management to define them."))

    # fields that need to be limited in length:
    lengths = {
        'code': max_field_length(Product, 'code'),
        'price': g.DECIMAL['currency_digits'] + 1,
        'purchase_price': g.DECIMAL['currency_digits'] + 1,
        'shortcut': max_field_length(Product, 'shortcut'),
        'stock': g.DECIMAL['quantity_digits'],
        'name': max_field_length(Product, 'name'),
        'tax': g.DECIMAL['percentage_decimal_places'] + 4,  # up to '100.' + 'decimal_digits'
    }
    
    context = {
        'company': c,
        'title': _("Products"),
        'site_title': g.MISC['site_title'],
        # lists
        'taxes': JsonStringify(get_all_taxes(request.user, c)),
        'categories': JsonStringify(get_all_categories(c, json=True)),
        'units': JsonStringify(g.UNITS),
        'discounts': JsonStringify(get_all_discounts(request.user, c)),
        # urls for ajax calls
        'add_url': reverse('pos:create_product', args=[c.url_name]),
        # config variables
        'can_edit': has_permission(request.user, c, 'product', 'edit'),
        'currency': get_company_value(request.user, c, 'pos_currency'),
        # images
        'image_dimensions': g.IMAGE_DIMENSIONS['product'],
        'image_upload_formats': g.MISC['image_upload_formats'], # what can be uploaded
        'max_upload_size': round(g.MISC['max_upload_image_size']/2**20, 2), # show in megabytes
        'max_upload_size_bytes': g.MISC['max_upload_image_size'], # bytes for javascript
        # html fields
        'field_lengths': lengths,
        'separator': get_company_value(request.user, c, 'pos_decimal_separator'),
        # numbers etc
        'default_tax_id': get_default_tax(request.user, c)['id'],
        'decimal_places': get_company_value(request.user, c, 'pos_decimal_places')*2,  # ACHTUNG: rounding comes at the end
    }
    return render(request, 'pos/manage/products.html', context)
Exemple #9
0
def manage_home(request, company):
    c = get_object_or_404(Company, url_name=company)
    
    # see if user has permission to view or edit management stuff
    if not has_permission(request.user, c, 'manage', 'view'):
        return no_permission_view(request, c, _("You have no permission to manage POS settings."))
    
    context = {
        'title': _("Management"),
        'site_title': g.MISC['site_title'],
        'company': c,
    }
    
    return render(request, 'pos/manage/manage.html', context)
Exemple #10
0
def edit_discount(request, company, discount_id):
    # edit an existing contact
    c = get_object_or_404(Company, url_name=company)
    
    # check permissions: needs to be at least manager
    if not has_permission(request.user, c, 'discount', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit discounts."))
    
    context = {
        'title': _("Edit discount"),
        'site_title': g.MISC['site_title'],
        'company': c,
        'discount_id': discount_id,
        'date_format_js': get_date_format(request.user, c, 'js'),
    }
    
    discount = get_object_or_404(Discount, id=discount_id)
        
    # check if contact actually belongs to the given company
    if discount.company != c:
        raise Http404
        
    if request.method == 'POST':
        # submit data
        form = DiscountForm(data=request.POST,
                            initial=discount_to_dict(request.user, c, discount),
                            company=c, user=request.user)

        if form.is_valid():
            discount.description = form.cleaned_data.get('description')
            discount.code = form.cleaned_data.get('code')
            discount.type = form.cleaned_data.get('type')
            discount.amount = form.cleaned_data.get('amount')
            discount.start_date = form.cleaned_data.get('start_date')
            discount.end_date = form.cleaned_data.get('end_date')
            discount.enabled = form.cleaned_data.get('enabled')
            discount.save()
            
            return redirect('pos:list_discounts', company=c.url_name)
    else:
        form = DiscountForm(initial=discount_to_dict(request.user, c, discount), user=request.user, company=c)

    context['form'] = form
    
    return render(request, 'pos/manage/discount.html', context)
Exemple #11
0
def list_registers(request, company):
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'register', 'view'):
        return no_permission_view(request, c, _("You have no permission to view registers."))
    
    context = {
        'company': c,
        'title': _("Cash Registers"),
        'registers': Register.objects.filter(company__id=c.id).order_by('name'),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'date_format_js': get_date_format(request.user, c, 'js'),
        'currency': get_company_value(request.user, c, 'pos_currency'),
    }

    return render(request, 'pos/manage/registers.html', context)
Exemple #12
0
def add_discount(request, company):
    c = get_object_or_404(Company, url_name=company)

    # check for permission for adding discounts
    if not has_permission(request.user, c, 'discount', 'edit'):
        return no_permission_view(request, c, _("You have no permission to add discounts."))
    
    context = {
        'title': _("Add discount"),
        'site_title': g.MISC['site_title'],
        'company': c,
        'date_format_js': get_date_format(request.user, c, 'js'),
    }

    if request.method == 'POST':
        # submit data
        form = DiscountForm(data=request.POST, user=request.user, company=c)

        if form.is_valid():
            # save the new discount and redirect back to discounts
            d = Discount(
                description=form.cleaned_data.get('description'),
                code=form.cleaned_data.get('code'),
                type=form.cleaned_data.get('type'),
                amount=form.cleaned_data.get('amount'),
                start_date=form.cleaned_data.get('start_date'),
                end_date=form.cleaned_data.get('end_date'),
                enabled=form.cleaned_data.get('enabled'),
                
                created_by=request.user,
                company=c
            )
            d.save()
            
            return redirect('pos:list_discounts', company=c.url_name)
    else:
        form = DiscountForm(user=request.user, company=c)

    context['form'] = form
    context['company'] = c
    context['add'] = True
    
    return render(request, 'pos/manage/discount.html', context)
Exemple #13
0
def company_settings(request, company):
    c = get_object_or_404(Company, url_name=company)

    # permissions
    if not has_permission(request.user, c, 'config', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit system configuration."))

    # get config
    initial = {
        'date_format': get_company_value(request.user, c, 'pos_date_format'),
        'time_format': get_company_value(request.user, c, 'pos_time_format'),
        'timezone': get_company_value(request.user, c, 'pos_timezone'),
        'currency': get_company_value(request.user, c, 'pos_currency'),
        'decimal_separator': get_company_value(request.user, c, 'pos_decimal_separator'),
        'decimal_places': get_company_value(request.user, c, 'pos_decimal_places'),
        'payment_bitcoin_address': get_company_value(request.user, c, 'pos_payment_bitcoin_address'),
        'payment_paypal_address': get_company_value(request.user, c, 'pos_payment_paypal_address'),
        'bill_serial_format': get_company_value(request.user, c, 'pos_bill_serial_format')
    }

    if request.method == 'POST':
        form = ConfigForm(request.POST)
        new_config = {}
        if form.is_valid():
            for key in initial:
                new_config['pos_' + key] = form.cleaned_data[key]

            save_company_config(request.user, c, new_config)

    else:
        form = ConfigForm(initial=initial)  # An unbound form

    context = {
        'company': c,
        'form': form,
        'title': _("System configuration"),
        'site_title': g.MISC['site_title'],
    }

    return render(request, 'pos/manage/config.html', context)
Exemple #14
0
def list_taxes(request, company):
    c = get_object_or_404(Company, url_name=company)
    
    # permissions
    list_permission = has_permission(request.user, c, 'tax', 'view')
    edit_permission = has_permission(request.user, c, 'tax', 'edit')
    
    if not list_permission:
        return no_permission_view(request, c, _("You have no permission to view taxes."))
    
    context = {
        'company': c,
        'taxes': JsonStringify(get_all_taxes(request.user, c)),
        'edit_permission': edit_permission,
        'max_name_length': max_field_length(Tax, 'name'),
        'title': _("Manage Tax Rates"),
        'site_title': g.MISC['site_title'],
        
        'separator': get_company_value(request.user, c, 'pos_decimal_separator'),
    }
    
    return render(request, 'pos/manage/tax.html', context)
Exemple #15
0
def user_settings(request, company):
    c = get_object_or_404(Company, url_name=company)

    # permissions
    if not has_permission(request.user, c, 'config', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit system configuration."))

    # get config: specify initial data manually (also for security reasons,
    # to not accidentally include secret data in request.POST or whatever)

    # this may be a little wasteful on resources, but config is only edited once in a lifetime or so
    # get_value is needed because dict['key'] will fail if new keys are added but not yet saved
    initial = {
        'product_button_size': get_user_value(request.user, 'pos_product_button_size'),
        'product_display': get_user_value(request.user, 'pos_product_display'),
        'display_breadcrumbs': get_user_value(request.user, 'pos_display_breadcrumbs'),
    }

    if request.method == 'POST':
        form = UserForm(request.POST)
        new_config = {}
        if form.is_valid():
            for key in initial:
                set_user_value(request.user, "pos_" + key, form.cleaned_data[key])
                # TODO: user settings
                # new_config['pos_' + key] = form.cleaned_data[key]
    else:
        form = UserForm(initial=initial)  # An unbound form

    context = {
        'company': c,
        'form': form,
        'title': _("User settings"),
        'site_title': g.MISC['site_title'],
    }

    return render(request, 'pos/manage/user.html', context)
Exemple #16
0
def edit_company(request, company):
    # get company, it must exist
    c = get_object_or_404(Company, url_name=company)

    # check if the user has permission to change it
    # only admins can change company details
    if not has_permission(request.user, c, 'company', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit company details."))

    context = {
        'company': c,
        'color_logo_dimensions': g.IMAGE_DIMENSIONS['color_logo'],
        'monochrome_logo_dimensions': g.IMAGE_DIMENSIONS['monochrome_logo'],
        'max_upload_size': g.MISC['max_upload_image_size'],

        'title': _("Company details"),
        'site_title': g.MISC['site_title'],
        'pos_url': get_terminal_url(request),
    }

    if request.method == 'POST':
        # submit data
        form = CompanyForm(request.POST, request.FILES, instance=c)
        
        if form.is_valid():
            form.save()

            # for an eventual message for the user
            context['saved'] = True
            # if url_name was changed, redirect to new address
            return redirect('pos:edit_company', company=c.url_name)
    else:
        form = CompanyForm(instance=c)
        
    context['form'] = form

    return render(request, 'pos/manage/company.html', context)
Exemple #17
0
def edit_register(request, company, register_id):
    # edit an existing register
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'register', 'edit'):
        return no_permission_view(request, c, _("You have no permission to edit registers."))

    context = {
        'company': c,
        'register_id': register_id,
        'title': _("Edit register"),
        'site_title': g.MISC['site_title'],
        'date_format_js': get_date_format(request.user, c, 'js'),
    }

    # get register
    register = get_object_or_404(Register, id=register_id, company=c)

    if request.method == 'POST':
        # submit data
        form = RegisterForm(request.POST, instance=register)

        if form.is_valid():
            form.save()

        return redirect('pos:list_registers', company=c.url_name)
    else:
        initial = register_to_dict(request.user, c, register)
        form = RegisterForm(initial=initial)
        form.user = request.user
        form.company = c

    context['form'] = form

    return render(request, 'pos/manage/register.html', context)
Exemple #18
0
def list_bills(request, company):
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'bill', 'view'):
        return no_permission_view(request, c, _("You have no permission to view bills."))

    N = 10  # if no search was made, display last N bills (below)
    searched = False

    # use GET for everything: there's little parameters and when using POST, paginator gets
    # in the way with GET requests
    form = BillSearchForm(data=request.GET, user=request.user, company=c)

    if form.is_valid():
        # decide which way to order the results
        # this is the fake switch statement that is missing in python for no obvious reason
        ordering = {
            'serial': 'serial',
            'date': 'timestamp',
            'amount': 'total'
        }
        order = ordering.get(form.cleaned_data.get('sort_by'))
        if form.cleaned_data.get('sort_order') == 'desc':
            order = '-' + order

        bills = Bill.objects.filter(company=c).order_by(order)

        # filter by whatever is in the form:
        # issue date: from
        t = form.cleaned_data.get('issued_from')
        if t:
            bills = bills.filter(timestamp__gte=t)

        # issue date: to
        t = form.cleaned_data.get('issued_to')
        if t:
            bills = bills.filter(timestamp__lte=t)

        # item:
        t = form.cleaned_data.get('item_code')
        if t:
            ids = [i.id for i in BillItem.objects.only('bill_id').filter(code__icontains=t)]

            # find all bills that include item that contains this code
            bills = bills.filter(id__in=ids)

        # contact
        t = form.cleaned_data.get('contact')
        if t:
            bills = bills.filter(contact__first_name__icontains=t) | \
                    bills.filter(contact__last_name__icontains=t) | \
                    bills.filter(contact__company_name__icontains=t)

        # bill number
        t = form.cleaned_data.get('serial')
        if t:
            bills = bills.filter(serial__icontains=t)

        # status
        t = form.cleaned_data.get('status')
        if t:
            bills = bills.filter(payment__status=t)

        # amount: from
        t = form.cleaned_data.get('amount_from')
        if t:
            bills = bills.filter(total__gte=t)

        # amount: to
        t = form.cleaned_data.get('amount_to')
        if t:
            bills = bills.filter(total__lte=t)

        # user
        t = form.cleaned_data.get('user_name')
        if t:
            bills = bills.filter(user_name__icontains=t)

        page = form.cleaned_data.get('page')
        searched = True
    else:
        form = BillSearchForm(data=None, user=request.user, company=c)
        page = 1

        bills = Bill.objects.filter(company=c).order_by('-timestamp')

    # format all bills manually
    bills = [bill_to_dict(request.user, c, b) for b in bills]

    paginator = Paginator(bills, g.MISC['bills_per_page'])
    if page:
        bills = paginator.page(page)
    else:
        bills = paginator.page(1)

    context = {
        'company': c,

        'bills': bills,
        'searched': searched,

        'filter_form': form,

        'title': _("Bills"),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'date_format_js': get_date_format(request.user, c, 'js'),
        'currency': get_company_value(request.user, c, 'pos_currency'),
    }

    return render(request, 'pos/manage/bills.html', context)
Exemple #19
0
def manage_stock(request, company, page):
    c = get_object_or_404(Company, url_name=company)

    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'stock', 'view'):
        return no_permission_view(request, c, _("You have no permission to view stock."))

    documents = Document.objects.filter(company=c).order_by('-number')

    search = request.GET.get('search', '')
    document = request.GET.get('document', '')

    if search == "":
        if document == "" or document == "all":
            stocks = Stock.objects.filter(company=c).order_by('-datetime_created')
        else:
            stocks = Stock.objects.filter(company=c, document=document).order_by('-datetime_created')
    else:
        stock_products = StockProduct.objects.filter(product__name__icontains=search, stock__in=[s.id for s in Stock.objects.filter(company=c)])
        stocks = Stock.objects.filter(Q(name__icontains=search) | Q(id__in=[sp.id for sp in stock_products]), Q(company=c)).order_by('-datetime_created')

    paginator = Paginator(stocks, g.MISC['stocks_per_page'])

    if page:
        stocks = paginator.page(page)
    else:
        stocks  = paginator.page(1)

    stocks_json = {}

    for s in stocks:
        s.stock_products = StockProduct.objects.filter(stock=s).order_by('product__name')
        __stock_products = {}

        for sp in s.stock_products:
            __stock_products[str(sp.id)] = {'product_id': str(sp.product.id), 'product_name': str(sp.product.name), 'deduction': str(fn(sp.deduction))}

        stocks_json[s.id] = {
            'id': str(s.id),
            'stock_type': s.stock_type,
            'unit_type': s.unit_type,
            'stock': fn(s.stock),
            'left_stock': fn(s.left_stock),
            'stock_products': __stock_products
        }

    currency = get_company_value(request.user, c, 'pos_currency')

    context = {
        'separator': get_company_value(request.user, c, 'pos_decimal_separator'),
        'currency': currency,
        'decimal_places': get_company_value(request.user, c, 'pos_decimal_places'),
        'currency_symbol': currencies[currency][1],
        'documents': documents,
        'managing': 'stock',
        'units': g.UNITS,
        'stock_types': g.STOCK_TYPE,
        'company': c,
        'stocks': stocks,
        'stocks_json': json.dumps(stocks_json),
        # 'searched': searched,
        # 'filter_form': form,
        'title': _("Stock"),
        'next_url': reverse('pos:manage_stock', args=[c.url_name, int(page)+1]),
        'prev_url': reverse('pos:manage_stock', args=[c.url_name, int(page)-1]),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'date_format_js': get_date_format(request.user, c, 'js'),
    }

    return render(request, 'pos/manage/manage_stocks.html', context)
Exemple #20
0
def stats(request, company):
    c = Company.objects.get(url_name=company)

    # permission?
    if not has_permission(request.user, c, 'stats', 'view'):
        return no_permission_view(request, c, _("You have no permission to view stats"))

    # recent earnings: all bills from today/yesterday/this week/this month,
    # their income and profit
    def bill_earnings(start_date=None, end_date=None):
        billset = Bill.objects.filter(company=c, payment__status=PAID)

        if start_date:
            billset = billset.filter(timestamp__gte=start_date)

        if end_date:
            billset = billset.filter(timestamp__lt=end_date)

        if billset.count() == 0:
            return {
                'income': format_number(request.user, c, Decimal(0)),
                'profit': format_number(request.user, c, Decimal(0)),
            }

        income = billset.aggregate(Sum('payment__total'))['payment__total__sum']

        return {
            'income': format_number(request.user, c, income),
            'profit': format_number(request.user, c,
                        income - billset.aggregate(Sum('base'))['base__sum'] -
                        billset.aggregate(Sum('discount'))['discount__sum'])
        }

    today = dtm.datetime.utcnow().replace(tzinfo=timezone(get_company_value(request.user, c, 'pos_timezone')))
    today = today.replace(hour=0, minute=0, second=0, microsecond=0)
    yesterday = today - dtm.timedelta(days=1)
    week_start = today - dtm.timedelta(days=today.weekday())
    month_start = today.replace(day=1)

    # get custom dates from form, if they are present
    earnings_from = None
    earnings_to = None

    if request.method == "GET":
        r = parse_date(request.user, c, request.GET.get('earnings_from'))
        if not r['success']:
            earnings_from = None
        else:
            earnings_from = r['date']

        r = parse_date(request.user, c, request.GET.get('earnings_to'))
        if not r['success']:
            earnings_to = None
        else:
            earnings_to = r['date']

        if earnings_from and earnings_to and earnings_from > earnings_to:
            earnings_from = None
            earnings_to = None

    if earnings_from and earnings_to:
        custom_earnings = bill_earnings(start_date=earnings_from, end_date=earnings_to)
    else:
        custom_earnings = None

    earnings = {
        'today': bill_earnings(start_date=today),
        'yesterday': bill_earnings(start_date=yesterday, end_date=today),
        'week': bill_earnings(start_date=week_start),
        'month': bill_earnings(start_date=month_start),
        'custom': custom_earnings,
    }

    # top-selling products:
    # today/yesterday/this week/this/month/overall
    TOP_PRODUCTS_LEN = 10

    def top_products(start_date=None, end_date=None):
        itemset = BillItem.objects.filter(bill__company=c, bill__payment__status=PAID)

        if start_date:
            itemset = itemset.filter(bill__timestamp__gte=start_date)

        if end_date:
            itemset = itemset.filter(bill__timestamp__lt=end_date)

        itemset = itemset.values('name', 'code')\
                         .annotate(sold_quantity=Sum('quantity'))\
                         .order_by('-sold_quantity')[:TOP_PRODUCTS_LEN]

        # make sure the list is always exactly TOP_PRODUCTS_LEN long
        itemset = list(itemset)
        itemset += [None for t in range(TOP_PRODUCTS_LEN - len(itemset))]

        return itemset

    # custom date limits from form
    products_from = None
    products_to = None

    if request.method == "GET":
        r = parse_date(request.user, c, request.GET.get('products_from'))
        if not r['success']:
            products_from = None
        else:
            products_from = r['date']

        r = parse_date(request.user, c, request.GET.get('products_to'))
        if not r['success']:
            products_to = None
        else:
            products_to = r['date']

        if products_from and products_to and products_from > products_to:
            products_from = None
            products_to = None

    if products_from and products_to:
        custom_products = top_products(start_date=products_from, end_date=products_to)
    else:
        custom_products = [None for x in range(TOP_PRODUCTS_LEN)]

    products_data = {
        'all_time': top_products(),
        'yesterday': top_products(start_date=yesterday, end_date=today),
        'week': top_products(start_date=week_start),
        'month': top_products(start_date=month_start),
        'custom': custom_products,
    }

    # convert the products from dict of lists to a simple list of rows for the template
    products = []
    for i in range(TOP_PRODUCTS_LEN):
        if not products_data['all_time'][i]:
            break

        products.append({
            'all_time': products_data['all_time'][i],
            'yesterday': products_data['yesterday'][i],
            'week': products_data['week'][i],
            'month': products_data['month'][i],
            'custom': products_data['custom'][i],
        })

    context = {
        'company': c,
        'earnings': earnings,
        'earnings_from': format_date(request.user, c, earnings_from),
        'earnings_to': format_date(request.user, c, earnings_to),

        'products': products,
        'products_from': format_date(request.user, c, products_from),
        'products_to': format_date(request.user, c, products_to),

        'title': _("Stats"),
        'site_title': g.SITE_TITLE,
        'date_format_js': get_date_format(request.user, c, 'js')
    }

    return render(request, 'pos/manage/stats.html', context)
Exemple #21
0
def list_discounts(request, company):
    c = get_object_or_404(Company, url_name=company)
    
    # check permissions: needs to be guest
    if not has_permission(request.user, c, 'discount', 'view'):
        return no_permission_view(request, c, _("You have no permission to view discounts."))
    
    N = 6
    searched = False

    # show the filter form
    form = DiscountFilterForm(data=request.GET, user=request.user, company=c)

    if form.is_valid():
        discounts = Discount.objects.filter(company__id=c.id)

        # filter by whatever is in the form: description
        if form.cleaned_data.get('search'):
            discounts = discounts.filter(description__icontains=form.cleaned_data['search']) | \
                        discounts.filter(code__icontains=form.cleaned_data['search'])

        # start_date
        t = form.cleaned_data.get('start_date')
        if t:
            discounts = discounts.filter(start_date__gte=t)

        # end_date
        t = form.cleaned_data.get('end_date')
        if t:
            discounts = discounts.filter(start_date__gte=t)

        # enabled
        t = form.cleaned_data.get('enabled')
        if t is not None:
            discounts = discounts.filter(enabled=t)

        page = form.cleaned_data.get('page')
        searched = True  # search results are being displayed
    else:
        form = DiscountFilterForm(user=request.user, company=c)
        discounts = Discount.objects.filter(company=c)[:N]
        page = 1

    paginator = Paginator(discounts, g.MISC['discounts_per_page'])
    if page:
        discounts = paginator.page(page)
    else:
        discounts = paginator.page(1)

    context = {
        'company': c,

        'discounts': discounts,
        'searched': searched,

        'filter_form': form,

        'title': _("Discounts"),
        'site_title': g.MISC['site_title'],
        'date_format_django': get_date_format(request.user, c, 'django'),
        'date_format_js': get_date_format(request.user, c, 'js'),
        'currency': get_company_value(request.user, c, 'pos_currency'),
    }

    return render(request, 'pos/manage/discounts.html', context)