示例#1
0
文件: events.py 项目: lucastx/vestat
def dias_de_deposito_events(begin, end):
    """
    Eventos que mostram a quantia que se espera que as bandeiras
    depositem referente a pagamentos com cartão.
    """

    pagamentos = PagamentoComCartao.objects.filter(
        data_do_deposito__range=(begin, end))

    dias = {}
    for p in pagamentos:
        dias.setdefault(p.data_do_deposito, []).append(p)

    for data, pagamentos in dias.items():

        valor_total = sum((p.valor - p.taxa) for p in pagamentos)
        nome = u"Entrada dos cartões: R$ {0}".format(
            format_currency(valor_total))

        descricao = "\n".join(
            u"R$ ({pgto} - {taxa}), {bandeira}, {data}".format(
                bandeira=p.bandeira,
                pgto=format_currency(p.valor),
                taxa=format_currency(p.taxa),
                data=format_date(p.venda.dia.data)) for p in pagamentos)

        yield Event(data, nome, descricao)
示例#2
0
def colorir_num(input):
    """Recebe um número e retorna o número marcado com a classe 'pos' se
    for positivo, ou 'neg' se for negativo."""
    try:
        if input > 0:
            s = 'R$ <span class="pos">%s</span>' % (format_currency(input))
        elif input == 0:
            s = 'R$ %s' % (format_currency(input))
        else:
            s = 'R$ <span class="neg">%s</span>' % (format_currency(input))
        return mark_safe(s)

    except (ValueError, TypeError):
        return input
示例#3
0
def colorir_num(input):
    """Recebe um número e retorna o número marcado com a classe 'pos' se
    for positivo, ou 'neg' se for negativo."""
    try:
        if input > 0:
            s = 'R$ <span class="pos">%s</span>' % (format_currency(input))
        elif input == 0:
            s = 'R$ %s' % (format_currency(input))
        else:
            s = 'R$ <span class="neg">%s</span>' % (format_currency(input))
        return mark_safe(s)
    
    except (ValueError, TypeError):
        return input
示例#4
0
文件: views.py 项目: lucastx/vestat
def pgtos_por_bandeira(dias):
    pgtos = PagamentoComCartao.objects.filter(venda__dia__in=dias)

    agrupado = {}
    for pgto in pgtos:
        key = (pgto.bandeira.nome)
        somar_dict(agrupado, key, {
            "pagamentos": 1,
            "entrada": pgto.valor,
        })

    dados = []
    for grupo in agrupado.keys():
        row = {}
        row["bandeira"] = grupo
        row["pagamentos"] = agrupado[grupo]["pagamentos"]
        row["entrada"] = format_currency(agrupado[grupo]["entrada"])
        dados.append(row)

    headers = ("bandeira", "pagamentos", "entrada")

    body = [[row[col] for col in headers] for row in dados]

    return {
        "title": "Pagamentos com cartão por bandeira",
        "headers": headers,
        "body": body
    }
示例#5
0
文件: views.py 项目: lucastx/vestat
def pgtos_por_bandeira(dias):
    pgtos = PagamentoComCartao.objects.filter(venda__dia__in=dias)

    agrupado = {}
    for pgto in pgtos:
        key = (pgto.bandeira.nome)
        somar_dict(agrupado, key, { "pagamentos": 1,
                                     "entrada": pgto.valor,
                                   })

    dados = []
    for grupo in agrupado.keys():
        row = {}
        row["bandeira"] = grupo
        row["pagamentos"] = agrupado[grupo]["pagamentos"]
        row["entrada"] = format_currency(agrupado[grupo]["entrada"])
        dados.append(row)

    headers = ("bandeira", "pagamentos", "entrada")

    body = [[row[col] for col in headers] for row in dados]

    return {
             "title": "Pagamentos com cartão por bandeira",
             "headers": headers,
             "body": body
           }
示例#6
0
文件: views.py 项目: lucastx/vestat
def vendas_por_dia_da_semana(dias):
    vendas = Venda.objects.filter(dia__in=dias)

    agrupado = {}
    for venda in vendas:
        key = venda.dia.categoria_semanal()
        somar_dict(agrupado, key, { "vendas": 1,
                                    "entrada": venda.conta,
                                    "pessoas": venda.num_pessoas,
                                    "permanencia_media": venda.permanencia })

    dados = []
    headers = ("categoria_semanal", "vendas", "entrada", "pessoas", "permanencia_media")
    for grupo in agrupado.keys():
        row = {}

        row["categoria_semanal"] = grupo
        for i, header in enumerate(headers[1:]):
            row[header] = agrupado[grupo][header]

        row["entrada"] = format_currency(row["entrada"])
        if row["permanencia_media"]:
            row["permanencia_media"] = secs_to_time(row["permanencia_media"] / row["vendas"])
        else:
            row["permanencia_media"] = 0
        dados.append(row)

    body = [[row[col] for col in headers] for row in dados]

    return {
             "title": "Vendas por dia de semana",
             "headers": headers,
             "body": body
           }
示例#7
0
文件: views.py 项目: lucastx/vestat
def vendas_por_mesa(dias):
    def split_and_strip(string, sep=","):
        """Splits a string using `sep` as a separator, and strips whitespace from the splitted results."""
        return map(lambda s: s.strip(), string.split(sep))
    
    def primeira_mesa(mesas):
        try:
            return int(split_and_strip(mesas)[0])
        except:
            return split_and_strip(mesas)[0]

    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("mesa").order_by("mesa")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("mesa", "vendas", "entrada", "pessoas", "permanencia_media")

    for row in dados:
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])
        row["entrada"] = format_currency(row["entrada"])
        row["mesa"] = row["mesa"].replace("/", ",")

    body = [[row[col] for col in headers] for row in dados]
    body.sort(key=lambda row: primeira_mesa(row[0]))

    return {
             "title": "Vendas por mesa",
             "headers": headers,
             "body": body
           }
示例#8
0
文件: views.py 项目: lucastx/vestat
def vendas_por_mesa(dias):
    def split_and_strip(string, sep=","):
        """Splits a string using `sep` as a separator, and strips whitespace from the splitted results."""
        return map(lambda s: s.strip(), string.split(sep))

    def primeira_mesa(mesas):
        try:
            return int(split_and_strip(mesas)[0])
        except:
            return split_and_strip(mesas)[0]

    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("mesa").order_by("mesa")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("mesa", "vendas", "entrada", "pessoas", "permanencia_media")

    for row in dados:
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])
        row["entrada"] = format_currency(row["entrada"])
        row["mesa"] = row["mesa"].replace("/", ",")

    body = [[row[col] for col in headers] for row in dados]
    body.sort(key=lambda row: primeira_mesa(row[0]))

    return {"title": "Vendas por mesa", "headers": headers, "body": body}
示例#9
0
def colorir_num_inverso(input):
    """Recebe um número e retorna o número marcado com a classe 'neg' se
    for positivo, ou 'pos' se for negativo -- ou seja, colore ele ao
    contrário do usual.
    
    Usado no mostrador de 10% a pagar -- que é bom se estiver negativo."""
    try:
        if input > 0:
            s = 'R$ <span class="neg">%s</span>' % (format_currency(input))
        elif input == 0:
            s = 'R$ %s' % (format_currency(input))
        else:
            s = 'R$ <span class="pos">%s</span>' % (format_currency(input))
        return mark_safe(s)

    except (ValueError, TypeError):
        return input
示例#10
0
def colorir_num_inverso(input):
    """Recebe um número e retorna o número marcado com a classe 'neg' se
    for positivo, ou 'pos' se for negativo -- ou seja, colore ele ao
    contrário do usual.
    
    Usado no mostrador de 10% a pagar -- que é bom se estiver negativo."""
    try:
        if input > 0:
            s = 'R$ <span class="neg">%s</span>' % (format_currency(input))
        elif input == 0:
            s = 'R$ %s' % (format_currency(input))
        else:
            s = 'R$ <span class="pos">%s</span>' % (format_currency(input))
        return mark_safe(s)
    
    except (ValueError, TypeError):
        return input
示例#11
0
文件: views.py 项目: lucastx/vestat
            def autolabel(ax, rects):
                """
                Rotula cada uma das barras com seu valor correspondente
                (ie total de despesas do mês)
                """

                for rect in rects:
                    height = rect.get_height()

                    text_x = rect.get_x() + rect.get_width() / 2.0

                    if rect.get_y() < 0:
                        text_y = -1 * (height + 900)
                    else:
                        text_y = height + 400

                    ax.text(text_x, text_y, "{0}".format(format_currency(height)),
                            ha='center', va='bottom', size='8')
示例#12
0
文件: views.py 项目: lucastx/vestat
def vendas_por_cidade(dias):
    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("cidade_de_origem")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("cidade_de_origem", "vendas", "entrada", "pessoas",
               "permanencia_media")

    for row in dados:
        row["entrada"] = format_currency(row["entrada"])
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])
        if not row["cidade_de_origem"]:
            row["cidade_de_origem"] = "---"

    body = [[row[col] for col in headers] for row in dados]

    return {"title": "Vendas por cidade", "headers": headers, "body": body}
示例#13
0
文件: views.py 项目: lucastx/vestat
            def autolabel(ax, rects):
                """
                Rotula cada uma das barras com seu valor correspondente
                (ie resultado do mês)
                """

                for rect in rects:
                    height = rect.get_height()

                    text_x = rect.get_x() + rect.get_width() / 2.0

                    if rect.get_y() < 0:
                        height *= -1
                        text_y = height - 500
                    else:
                        text_y = height + 200

                    ax.text(text_x, text_y, "{0}".format(format_currency(height)),
                            ha='center', va='bottom', size='8')
示例#14
0
文件: views.py 项目: lucastx/vestat
def vendas_por_categoria(dias):
    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("categoria")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("categoria", "vendas", "entrada", "pessoas",
               "permanencia_media")

    for row in dados:
        row["entrada"] = format_currency(row["entrada"])
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])

    body = [[row[col] for col in headers] for row in dados]

    for row in body:
        row[0] = dict(Venda.CATEGORIA_CHOICES)[row[0]]

    return {"title": "Vendas por categoria", "headers": headers, "body": body}
示例#15
0
文件: views.py 项目: lucastx/vestat
def vendas_por_cidade(dias):
    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("cidade_de_origem")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("cidade_de_origem", "vendas", "entrada", "pessoas", "permanencia_media")

    for row in dados:
        row["entrada"] = format_currency(row["entrada"])
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])
        if not row["cidade_de_origem"]:
            row["cidade_de_origem"] = "---"

    body = [[row[col] for col in headers] for row in dados]

    return {
             "title": "Vendas por cidade",
             "headers": headers,
             "body": body
           }
示例#16
0
文件: views.py 项目: lucastx/vestat
            def autolabel(ax, rects):
                """
                Rotula cada uma das barras com seu valor correspondente
                (ie total de despesas do mês)
                """

                for rect in rects:
                    height = rect.get_height()

                    text_x = rect.get_x() + rect.get_width() / 2.0

                    if rect.get_y() < 0:
                        text_y = -1 * (height + 900)
                    else:
                        text_y = height + 400

                    ax.text(text_x,
                            text_y,
                            "{0}".format(format_currency(height)),
                            ha='center',
                            va='bottom',
                            size='8')
示例#17
0
文件: views.py 项目: lucastx/vestat
def vendas_por_dia_da_semana(dias):
    vendas = Venda.objects.filter(dia__in=dias)

    agrupado = {}
    for venda in vendas:
        key = venda.dia.categoria_semanal()
        somar_dict(
            agrupado, key, {
                "vendas": 1,
                "entrada": venda.conta,
                "pessoas": venda.num_pessoas,
                "permanencia_media": venda.permanencia
            })

    dados = []
    headers = ("categoria_semanal", "vendas", "entrada", "pessoas",
               "permanencia_media")
    for grupo in agrupado.keys():
        row = {}

        row["categoria_semanal"] = grupo
        for i, header in enumerate(headers[1:]):
            row[header] = agrupado[grupo][header]

        row["entrada"] = format_currency(row["entrada"])
        if row["permanencia_media"]:
            row["permanencia_media"] = secs_to_time(row["permanencia_media"] /
                                                    row["vendas"])
        else:
            row["permanencia_media"] = 0
        dados.append(row)

    body = [[row[col] for col in headers] for row in dados]

    return {
        "title": "Vendas por dia de semana",
        "headers": headers,
        "body": body
    }
示例#18
0
文件: views.py 项目: lucastx/vestat
            def autolabel(ax, rects):
                """
                Rotula cada uma das barras com seu valor correspondente
                (ie resultado do mês)
                """

                for rect in rects:
                    height = rect.get_height()

                    text_x = rect.get_x() + rect.get_width() / 2.0

                    if rect.get_y() < 0:
                        height *= -1
                        text_y = height - 500
                    else:
                        text_y = height + 200

                    ax.text(text_x,
                            text_y,
                            "{0}".format(format_currency(height)),
                            ha='center',
                            va='bottom',
                            size='8')
示例#19
0
文件: views.py 项目: lucastx/vestat
def vendas_por_categoria(dias):
    vendas = Venda.objects.filter(dia__in=dias)
    agrupado = vendas.values("categoria")
    dados = agrupado.annotate(vendas=Count("id"),
                              entrada=Sum("conta"),
                              pessoas=Sum("num_pessoas"),
                              permanencia_media=Avg("permanencia"))
    headers = ("categoria", "vendas", "entrada", "pessoas", "permanencia_media")

    for row in dados:
        row["entrada"] = format_currency(row["entrada"])
        row["permanencia_media"] = secs_to_time(row["permanencia_media"])

    body = [[row[col] for col in headers] for row in dados]

    for row in body:
        row[0] = dict(Venda.CATEGORIA_CHOICES)[row[0]]

    return {
             "title": "Vendas por categoria",
             "headers": headers,
             "body": body
           }
示例#20
0
文件: views.py 项目: lucastx/vestat
    def body(self):
        despesas = list(DespesaDeCaixa.objects.filter(dia__in=self.data)) + \
                list(MovimentacaoBancaria.objects.filter(dia__in=self.data, valor__lt=0))

        self._total_despesas = Decimal(sum(d.valor for d in despesas))

        if not self._total_despesas:
            return []

        vendas = Venda.objects.filter(dia__in=self.data)
        total_vendas = Decimal(sum(v.conta for v in vendas))

        categoria_dict_dict = {}

        # Acumula despesas com `categoria == None`
        outros = {
            "total": Decimal("0"),
        }

        for despesa in despesas:
            if despesa.categoria:
                caminho_categorias = [despesa.categoria] + despesa.categoria.ascendentes

                for categoria in caminho_categorias:
                    categoria_dict = categoria_dict_dict.setdefault(categoria.slug, {
                            "total": Decimal("0"),
                            "outros": {
                                "total": Decimal("0"),
                            },
                    })

                    categoria_dict["total"] += despesa.valor

                categoria_dict = categoria_dict_dict[categoria.slug]

                # Se a categoria tem filhos, a despesa deve ser categorizada como
                # "Outros".
                #
                # Ex: se há "Fornecedor > Vinhos" e a despesa está como
                # "Fornecedor", deve ser listada como "Fornecedor > Outros"

                if despesa.categoria.filhas.count():
                    categoria_dict["outros"]["total"] += despesa.valor
            else:
                logger.debug(u"Despesa sem categoria: {0}".format(despesa))
                outros["total"] += despesa.valor


        logger.debug(u"Total de despesas sem categoria: {0}".format(len([d for d in despesas if not d.categoria])))


        # Calcula porcentagem em relação à despesa total
        for categoria_dict in categoria_dict_dict.values():
            razao_das_despesas = abs(categoria_dict["total"] / self._total_despesas)
            razao_das_vendas = abs(categoria_dict["total"] / total_vendas)

            categoria_dict["porcentagem_das_despesas"] = "{:.2%}".format(razao_das_despesas)
            categoria_dict["porcentagem_das_vendas"] = "{:.2%}".format(razao_das_vendas)

            if categoria_dict["outros"]["total"]:
                razao_das_despesas = abs(categoria_dict["outros"]["total"] / self._total_despesas)
                razao_das_vendas = abs(categoria_dict["outros"]["total"] / total_vendas)

                categoria_dict["outros"]["porcentagem_das_despesas"] = "{:.2%}".format(razao_das_despesas)
                categoria_dict["outros"]["porcentagem_das_vendas"] = "{:.2%}".format(razao_das_vendas)


        razao_das_despesas_outros = abs(outros["total"] / self._total_despesas)
        razao_das_vendas_outros = abs(outros["total"] / total_vendas)

        outros["porcentagem_das_despesas"] = "{:.2%}".format(razao_das_despesas_outros)
        outros["porcentagem_das_vendas"] = "{:.2%}".format(razao_das_vendas_outros)


        categoria_tuple_list = []
        for slug, categoria_dict in categoria_dict_dict.items():
            categoria = CategoriaDeMovimentacao.objects.get(slug=slug)

            if categoria.filhas.count():
                nome = u"{0} - Total".format(categoria.nome_completo)
            else:
                nome = categoria.nome_completo

            categoria_tuple_list.append((
                nome,
                format_currency(categoria_dict["total"]),
                categoria_dict["porcentagem_das_despesas"],
                categoria_dict["porcentagem_das_vendas"],
            ))

            if categoria_dict["outros"]["total"]:
                categoria_tuple_list.append((
                    categoria.SEPARADOR.join([categoria.nome_completo, "Outros"]),
                    format_currency(categoria_dict["outros"]["total"]),
                    categoria_dict["outros"]["porcentagem_das_despesas"],
                    categoria_dict["outros"]["porcentagem_das_vendas"],
                ))

        if outros["total"]:
            categoria_tuple_list.append((
                u"Outros",
                format_currency(outros["total"]),
                outros["porcentagem_das_despesas"],
                outros["porcentagem_das_vendas"],
            ))

        return sorted(categoria_tuple_list, key=lambda r: r[0]) # Ordena por nome completo da categoria
示例#21
0
文件: views.py 项目: lucastx/vestat
    def body(self):
        despesas = list(DespesaDeCaixa.objects.filter(dia__in=self.data)) + \
                list(MovimentacaoBancaria.objects.filter(dia__in=self.data, valor__lt=0))

        self._total_despesas = Decimal(sum(d.valor for d in despesas))

        if not self._total_despesas:
            return []

        vendas = Venda.objects.filter(dia__in=self.data)
        total_vendas = Decimal(sum(v.conta for v in vendas))

        categoria_dict_dict = {}

        # Acumula despesas com `categoria == None`
        outros = {
            "total": Decimal("0"),
        }

        for despesa in despesas:
            if despesa.categoria:
                caminho_categorias = [despesa.categoria
                                      ] + despesa.categoria.ascendentes

                for categoria in caminho_categorias:
                    categoria_dict = categoria_dict_dict.setdefault(
                        categoria.slug, {
                            "total": Decimal("0"),
                            "outros": {
                                "total": Decimal("0"),
                            },
                        })

                    categoria_dict["total"] += despesa.valor

                categoria_dict = categoria_dict_dict[categoria.slug]

                # Se a categoria tem filhos, a despesa deve ser categorizada como
                # "Outros".
                #
                # Ex: se há "Fornecedor > Vinhos" e a despesa está como
                # "Fornecedor", deve ser listada como "Fornecedor > Outros"

                if despesa.categoria.filhas.count():
                    categoria_dict["outros"]["total"] += despesa.valor
            else:
                logger.debug(u"Despesa sem categoria: {0}".format(despesa))
                outros["total"] += despesa.valor

        logger.debug(u"Total de despesas sem categoria: {0}".format(
            len([d for d in despesas if not d.categoria])))

        # Calcula porcentagem em relação à despesa total
        for categoria_dict in categoria_dict_dict.values():
            razao_das_despesas = abs(categoria_dict["total"] /
                                     self._total_despesas)
            razao_das_vendas = abs(categoria_dict["total"] / total_vendas)

            categoria_dict["porcentagem_das_despesas"] = "{:.2%}".format(
                razao_das_despesas)
            categoria_dict["porcentagem_das_vendas"] = "{:.2%}".format(
                razao_das_vendas)

            if categoria_dict["outros"]["total"]:
                razao_das_despesas = abs(categoria_dict["outros"]["total"] /
                                         self._total_despesas)
                razao_das_vendas = abs(categoria_dict["outros"]["total"] /
                                       total_vendas)

                categoria_dict["outros"][
                    "porcentagem_das_despesas"] = "{:.2%}".format(
                        razao_das_despesas)
                categoria_dict["outros"][
                    "porcentagem_das_vendas"] = "{:.2%}".format(
                        razao_das_vendas)

        razao_das_despesas_outros = abs(outros["total"] / self._total_despesas)
        razao_das_vendas_outros = abs(outros["total"] / total_vendas)

        outros["porcentagem_das_despesas"] = "{:.2%}".format(
            razao_das_despesas_outros)
        outros["porcentagem_das_vendas"] = "{:.2%}".format(
            razao_das_vendas_outros)

        categoria_tuple_list = []
        for slug, categoria_dict in categoria_dict_dict.items():
            categoria = CategoriaDeMovimentacao.objects.get(slug=slug)

            if categoria.filhas.count():
                nome = u"{0} - Total".format(categoria.nome_completo)
            else:
                nome = categoria.nome_completo

            categoria_tuple_list.append((
                nome,
                format_currency(categoria_dict["total"]),
                categoria_dict["porcentagem_das_despesas"],
                categoria_dict["porcentagem_das_vendas"],
            ))

            if categoria_dict["outros"]["total"]:
                categoria_tuple_list.append((
                    categoria.SEPARADOR.join(
                        [categoria.nome_completo, "Outros"]),
                    format_currency(categoria_dict["outros"]["total"]),
                    categoria_dict["outros"]["porcentagem_das_despesas"],
                    categoria_dict["outros"]["porcentagem_das_vendas"],
                ))

        if outros["total"]:
            categoria_tuple_list.append((
                u"Outros",
                format_currency(outros["total"]),
                outros["porcentagem_das_despesas"],
                outros["porcentagem_das_vendas"],
            ))

        return sorted(
            categoria_tuple_list,
            key=lambda r: r[0])  # Ordena por nome completo da categoria