def discount_to_dict(user, company, d, android=False): ret = { 'id': d.id, 'description': d.description, 'code': d.code, 'type': d.type, 'amount': format_number(user, company, d.amount, True), 'enabled': d.enabled, 'active': d.is_active, } if android and d.start_date: ret['start_date'] = [d.start_date.year, d.start_date.month, d.start_date.day] else: ret['start_date'] = format_date(user, company, d.start_date) if android and d.end_date: ret['end_date'] = [d.end_date.year, d.end_date.month, d.end_date.day] else: ret['end_date'] = format_date(user, company, d.end_date) return ret
def payment_to_dict(user, company, payment): return { "type": payment.type, "amount_paid": format_number(user, company, payment.amount_paid), "currency": payment.currency, "total": format_number(user, company, payment.total), "total_btc": format_number(user, company, payment.total_btc), "transaction_datetime": format_date(user, company, payment.transaction_datetime), "btc_transaction_reference": payment.btc_transaction_reference, "paypal_transaction_reference": payment.paypal_transaction_reference, "payment_info": payment.payment_info, "status": payment.get_status_display(), }
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)
def contact_to_dict(user, company, c): # returns all relevant contact's data # id # type # company_name # first_name # last_name # date_of_birth # street_address # postcode # city # country # email # phone # vat ret = { 'id': c.id, 'type': c.type, } # a human-readable and quickly-accessible contact name # ret['name'] = '' if c.company_name: ret['name'] = c.company_name else: if c.first_name: ret['name'] = c.first_name + ' ' if c.last_name: ret['name'] += c.last_name if c.company_name: ret['company_name'] = c.company_name if c.first_name: ret['first_name'] = c.first_name if c.last_name: ret['last_name'] = c.last_name if c.sex: ret['sex'] = c.sex if c.date_of_birth: ret['date_of_birth'] = format_date(user, company, c.date_of_birth) if c.street_address: ret['street_address'] = c.street_address if c.postcode: ret['postcode'] = c.postcode if c.city: ret['city'] = c.city if c.state: ret['state'] = c.state if c.country: ret['country'] = c.country ret['country_name'] = c.country_name if c.email: ret['email'] = c.email if c.phone: ret['phone'] = c.phone if c.vat: ret['vat'] = c.vat if c.additional_info: ret['additional_info'] = c.additional_info return ret
def bill_to_dict(user, company, bill): # fields in bill: # company # type # recipient_contact > FK contact # note # sub_total | # discount | decimal fields, with everything calculated # tax | # timestamp # status > choices in g.BILL_STATUS b = { "id": bill.id, "issuer": company_to_dict(user, bill.issuer), "register": register_to_dict(user, company, bill.register), "user_id": bill.user_id, "user_name": bill.user_name, "serial": bill.serial, "serial_prefix": bill.serial_prefix, "serial_number": bill.serial_number, "notes": bill.notes, "discount_amount": format_number(user, company, bill.discount_amount), "discount_type": bill.discount_type, "currency": bill.payment.currency, # prices "base": format_number(user, company, bill.base), "discount": format_number(user, company, bill.discount), "tax": format_number(user, company, bill.tax), "total": format_number(user, company, bill.total), "timestamp": format_date(user, company, bill.timestamp) + " " + format_time(user, company, bill.timestamp), } if bill.contact: b["contact"] = contact_to_dict(user, company, bill.contact) # get items items = list(BillItem.objects.filter(bill=bill)) # gather tax rates for all items grouped_taxes = group_tax_rates(items) tax_rates = grouped_taxes["rates"] tax_sums = grouped_taxes["sums"] for rate in tax_rates: rate["amount"] = format_number(user, company, rate["amount"]) rate["tax_sum"] = format_number(user, company, rate["tax_sum"]) rate["net_sum"] = format_number(user, company, rate["net_sum"]) rate["gross_sum"] = format_number(user, company, rate["gross_sum"]) tax_sums["tax_sum"] = format_number(user, company, tax_sums["tax_sum"]) tax_sums["net_sum"] = format_number(user, company, tax_sums["net_sum"]) tax_sums["gross_sum"] = format_number(user, company, tax_sums["gross_sum"]) b["tax_rates"] = tax_rates b["tax_sums"] = tax_sums # format all items i = [] for item in items: i.append(bill_item_to_dict(user, company, item)) b["items"] = i b["payment"] = payment_to_dict(user, company, bill.payment) return b