Esempio n. 1
0
    def response(self, request, queryset):
        if request.GET.get("export") == "pdf":
            if not queryset.exists():
                messages.warning(request, _("No invoices found."))
                return HttpResponseRedirect("?error=1")

            count = queryset.count()
            if count > settings.BATCH_MAX_ITEMS:
                messages.error(
                    request,
                    _("%s invoices in selection, that's too many.") % count)
                return HttpResponseRedirect("?error=1")

            pdf, response = pdf_response(
                "invoices",
                as_attachment=request.GET.get("disposition") == "attachment",
            )
            for invoice in queryset:
                pdf.init_letter()
                pdf.process_invoice(invoice)
                pdf.restart()
            pdf.generate()
            return response

        if request.GET.get("export") == "xlsx":
            xlsx = WorkbenchXLSXDocument()
            xlsx.table_from_queryset(queryset)
            return xlsx.to_response("invoices.xlsx")
Esempio n. 2
0
def paid_debtors_zip(date_range, *, file):
    activate(settings.WORKBENCH.PDF_LANGUAGE)
    xlsx = WorkbenchXLSXDocument()

    with zipfile.ZipFile(file, "w", compression=zipfile.ZIP_DEFLATED) as zf:
        for ledger in Ledger.objects.all():
            rows = []
            for entry in (CreditEntry.objects.filter(
                    ledger=ledger, value_date__range=date_range).order_by(
                        "value_date").select_related("invoice__project",
                                                     "invoice__owned_by")):
                rows.append((
                    entry.value_date,
                    entry.total,
                    entry.payment_notice,
                    entry.invoice,
                    entry.notes,
                ))

                if entry.invoice:
                    append_invoice(
                        zf=zf,
                        ledger_slug=slugify(ledger.name),
                        invoice=entry.invoice,
                    )

            xlsx.add_sheet(slugify(ledger.name))
            xlsx.table(
                (
                    _("value date"),
                    _("total"),
                    _("payment notice"),
                    _("invoice"),
                    _("notes"),
                ),
                rows,
            )

        rows = []
        for invoice in (Invoice.objects.filter(
                closed_on__range=date_range,
                status=Invoice.PAID).exclude(pk__in=CreditEntry.objects.filter(
                    invoice__isnull=False).values("invoice")).order_by(
                        "closed_on").select_related("project")):
            rows.append((invoice.closed_on, invoice.total,
                         invoice.payment_notice, invoice))

            append_invoice(zf=zf, ledger_slug="unknown", invoice=invoice)

        xlsx.add_sheet("unknown")
        xlsx.table(
            (_("closed on"), _("total"), _("payment notice"), _("invoice")),
            rows)

        with io.BytesIO() as buf:
            xlsx.workbook.save(buf)
            zf.writestr("debtors.xlsx", buf.getvalue())
Esempio n. 3
0
    def response(self, request, queryset):
        if request.GET.get("export") == "xlsx":
            xlsx = WorkbenchXLSXDocument()
            xlsx.people(queryset)
            return xlsx.to_response("people.xlsx")

        elif request.GET.get("export") == "vcard":
            return render_vcard_response(
                request,
                "\n".join(
                    person_to_vcard(person).serialize()
                    for person in queryset.prefetch_related(
                        "phonenumbers", "emailaddresses", "postaladdresses")
                    [:settings.BATCH_MAX_ITEMS]),
            )
Esempio n. 4
0
def open_items_list(request, form):
    if request.GET.get("export") == "xlsx":
        xlsx = WorkbenchXLSXDocument()
        xlsx.table_from_queryset(form.open_items_list()["list"].select_related(
            "customer", "contact__organization", "owned_by",
            "project__owned_by"))
        return xlsx.to_response("open-items-list-{}.xlsx".format(
            form.cleaned_data["cutoff_date"].isoformat()))

    return render(
        request,
        "reporting/open_items_list.html",
        {
            "form": form,
            "open_items_list": form.open_items_list()
        },
    )
Esempio n. 5
0
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()

        data = [
            [
                gettext("service"),
                gettext("description"),
                gettext("rendered on"),
                gettext("effort type"),
                gettext("hourly rate"),
                gettext("hours"),
                gettext("cost"),
            ],
            [],
        ]

        hours = defaultdict(list)
        cost = defaultdict(list)

        for entry in LoggedHours.objects.filter(
                invoice_service__invoice=self.object):
            hours[entry.invoice_service_id].append(entry)
        for entry in LoggedCost.objects.filter(
                invoice_service__invoice=self.object):
            cost[entry.invoice_service_id].append(entry)

        for service in self.object.services.all():
            data.append([
                service.title,
                service.description,
                "",
                service.effort_type,
                service.effort_rate,
                "",
                "",
            ])
            for entry in hours[service.id]:
                data.append([
                    "",
                    entry.description,
                    entry.rendered_on,
                    "",
                    "",
                    entry.hours,
                    entry.hours *
                    service.effort_rate if service.effort_rate else "",
                ])
            for entry in cost[service.id]:
                data.append([
                    "", entry.description, entry.rendered_on, "", "", "",
                    entry.cost
                ])
            data.append([])

        xlsx = WorkbenchXLSXDocument()
        xlsx.add_sheet(gettext("logbook"))
        xlsx.table(None, data)
        return xlsx.to_response("%s.xlsx" % self.object.code)
Esempio n. 6
0
def project_budget_statistics_view(request, form):
    statistics = project_budget_statistics.project_budget_statistics(
        form.queryset(), cutoff_date=form.cleaned_data.get("cutoff_date")
    )

    if form.cleaned_data.get("closed_during_the_last_year"):
        statistics["statistics"] = sorted(
            statistics["statistics"], key=lambda s: s["project"].closed_on, reverse=True
        )

    if request.GET.get("export") == "xlsx" and statistics["statistics"]:
        xlsx = WorkbenchXLSXDocument()
        xlsx.project_budget_statistics(statistics)
        return xlsx.to_response("project-budget-statistics.xlsx")

    return render(
        request,
        "reporting/project_budget_statistics.html",
        {"form": form, "statistics": statistics},
    )
Esempio n. 7
0
def annual_working_time_pdf(statistics):
    if len(statistics["statistics"]) == 1:
        response = HttpResponse(user_stats_pdf(statistics["statistics"][0]),
                                content_type="application/pdf")
        response["Content-Disposition"] = 'attachment; filename="awt.pdf"'
        return response

    with io.BytesIO() as buf:
        with zipfile.ZipFile(buf, "w", compression=zipfile.ZIP_DEFLATED) as zf:
            for data in statistics["statistics"]:
                zf.writestr(
                    "%s-%s.pdf" % (
                        slugify(data["user"].get_full_name()),
                        data["months"]["year"].year,
                    ),
                    user_stats_pdf(data),
                )
            xlsx = WorkbenchXLSXDocument()
            xlsx.add_sheet(_("running net work hours"))
            xlsx.table(
                [""] +
                [date_format(day, "M") for day in data["months"]["months"]] +
                [_("vacation days credit")],
                [[data["user"].get_full_name()] + data["running_sums"] +
                 [data["totals"]["vacation_days_credit"]]
                 for data in statistics["statistics"]],
            )
            with io.BytesIO() as x:
                xlsx.workbook.save(x)
                zf.writestr("statistics.xlsx", x.getvalue())
        response = HttpResponse(buf.getvalue(), content_type="application/zip")
        response["Content-Disposition"] = 'attachment; filename="awt.zip"'
        return response
Esempio n. 8
0
    def response(self, request, queryset):
        if request.GET.get("export") == "xlsx":
            xlsx = WorkbenchXLSXDocument()
            additional = []
            values = {(v.deal_id, v.type_id): v.value
                      for v in Value.objects.filter(deal__in=queryset)}
            attributes = {(a.deal_id, a.attribute.group_id): a.attribute
                          for a in DealAttribute.objects.filter(
                              deal__in=queryset).select_related("attribute")}

            for vt in ValueType.objects.all():
                additional.append((
                    "{}: {}".format(Value._meta.verbose_name, vt),
                    (lambda id: lambda deal: values.get((deal.id, id)))(vt.id),
                ))
            for ag in AttributeGroup.objects.all():
                additional.append((
                    "{}: {}".format(Attribute._meta.verbose_name, ag),
                    (lambda id: lambda deal: attributes.get(
                        (deal.id, id)))(ag.id),
                ))
            xlsx.table_from_queryset(queryset, additional=additional)
            return xlsx.to_response("deals.xlsx")
Esempio n. 9
0
 def response(self, request, queryset):
     if (request.GET.get("export") == "xlsx"
             and request.user.features[FEATURES.CONTROLLING]):
         xlsx = WorkbenchXLSXDocument()
         xlsx.table_from_queryset(queryset)
         return xlsx.to_response("absences.xlsx")
Esempio n. 10
0
 def response(self, request, queryset):
     if (request.GET.get("export") == "xlsx"
             and request.user.features[FEATURES.CONTROLLING]):
         xlsx = WorkbenchXLSXDocument()
         xlsx.logged_costs(queryset)
         return xlsx.to_response("costs.xlsx")
Esempio n. 11
0
    def handle(self, **options):
        activate("de")

        invoiced_per_customer = {
            row["customer"]:
            row["total_excl_tax__sum"] - row["third_party_costs__sum"]
            for row in Invoice.objects.invoiced().filter(
                project__isnull=False).order_by().values("customer").annotate(
                    Sum("total_excl_tax"), Sum("third_party_costs"))
        }
        hours = defaultdict(lambda: defaultdict(lambda: Z1))
        earned = defaultdict(lambda: defaultdict(lambda: Z1))
        customer_hours = defaultdict(lambda: Z1)
        user_hours = defaultdict(lambda: Z1)

        for row in (LoggedHours.objects.order_by().values(
                "service__project__customer",
                "rendered_by").annotate(Sum("hours"))):
            hours[row["service__project__customer"]][
                row["rendered_by"]] = row["hours__sum"]
            customer_hours[
                row["service__project__customer"]] += row["hours__sum"]
            user_hours[row["rendered_by"]] += row["hours__sum"]

        for customer, total_excl_tax in invoiced_per_customer.items():
            _c_hours = sum(hours[customer].values(), Z1)
            if not total_excl_tax:
                continue
            if not _c_hours:
                print(
                    "No hours for customer",
                    customer,
                    "with",
                    total_excl_tax,
                    Organization.objects.get(pk=customer),
                )
                continue
            for user, _u_hours in hours[customer].items():
                earned[customer][user] += _u_hours / _c_hours * total_excl_tax

        customers = sorted(
            (with_rate(
                {
                    "customer": customer,
                    "invoiced": invoiced_per_customer.get(customer.id, Z1),
                    "hours": customer_hours[customer.id],
                },
                "invoiced",
            ) for customer in Organization.objects.filter(
                id__in=earned.keys())),
            key=lambda row: row["rate"],
            reverse=True,
        )
        users = sorted(
            (with_rate(
                {
                    "user": user,
                    "earned": sum((c[user.id] for c in earned.values()), Z1),
                    "hours": user_hours[user.id],
                },
                "earned",
            ) for user in User.objects.filter(id__in=user_hours)),
            key=lambda row: row["rate"],
            reverse=True,
        )

        data = []
        data = [
            ["", "", "", _("user")] + [u["user"] for u in users],
            ["", "", "", _("earned")] + [u["earned"] for u in users],
            ["", "", "", _("hours")] + [u["hours"] for u in users],
            [_("customer"),
             _("invoiced"),
             _("hours"), _("rate")] + [u["rate"] for u in users],
        ]

        for c in customers:
            data.extend([
                [c["customer"], c["invoiced"], c["hours"], c["rate"]] +
                [hours[c["customer"].id][u["user"].id] or None for u in users],
                ["", "", "", ""] + [
                    earned[c["customer"].id][u["user"].id] or None
                    for u in users
                ],
            ])

        xlsx = WorkbenchXLSXDocument()
        xlsx.add_sheet("profitability")
        xlsx.table(None, data)
        xlsx.workbook.save("profitability.xlsx")