<commit_before>from __future__ import unicode_literals

import datetime
from django.conf import settings
from rest_framework import serializers
from rest_framework.reverse import reverse

from waldur_core.core import serializers as core_serializers
from waldur_core.core import utils as core_utils
from waldur_mastermind.common.utils import quantize_price

from . import models


class InvoiceItemSerializer(serializers.HyperlinkedModelSerializer):
    tax = serializers.DecimalField(max_digits=15, decimal_places=7)
    total = serializers.DecimalField(max_digits=15, decimal_places=7)
    factor = serializers.ReadOnlyField(source='get_factor')

    scope_type = serializers.SerializerMethodField()
    scope_uuid = serializers.SerializerMethodField()

    class Meta(object):
        model = models.InvoiceItem
        fields = ('name', 'price', 'tax', 'total', 'unit_price', 'unit', 'factor',
                  'start', 'end', 'product_code', 'article_code', 'project_name', 'project_uuid',
                  'scope_type', 'scope_uuid',)

    def get_scope_type(self, item):
        # It should be implemented by inherited class
        return

    def get_scope_uuid(self, item):
        # It should be implemented by inherited class
        return


class GenericItemSerializer(InvoiceItemSerializer):
    details = serializers.JSONField()

    class Meta(InvoiceItemSerializer.Meta):
        model = models.GenericInvoiceItem
        fields = InvoiceItemSerializer.Meta.fields + ('quantity', 'details', 'usage_days',)

    def get_scope_type(self, item):
        try:
            return item.content_type.model_class().get_scope_type()
        except AttributeError:
            return None

    def get_scope_uuid(self, item):
        if item.scope:
            return item.scope.uuid.hex
        return item.details.get('scope_uuid')


class InvoiceSerializer(core_serializers.RestrictedSerializerMixin,
                        serializers.HyperlinkedModelSerializer):
    price = serializers.DecimalField(max_digits=15, decimal_places=7)
    tax = serializers.DecimalField(max_digits=15, decimal_places=7)
    total = serializers.DecimalField(max_digits=15, decimal_places=7)
    items = GenericItemSerializer(many=True)
    issuer_details = serializers.SerializerMethodField()
    customer_details = serializers.SerializerMethodField()
    due_date = serializers.DateField()
    file = serializers.SerializerMethodField()

    class Meta(object):
        model = models.Invoice
        fields = (
            'url', 'uuid', 'number', 'customer', 'price', 'tax', 'total',
            'state', 'year', 'month', 'issuer_details', 'invoice_date', 'due_date',
            'customer', 'customer_details', 'items', 'file',
        )
        extra_kwargs = {
            'url': {'lookup_field': 'uuid'},
            'customer': {'lookup_field': 'uuid'},
        }

    def get_issuer_details(self, invoice):
        return settings.WALDUR_INVOICES['ISSUER_DETAILS']

    def get_customer_details(self, invoice):
        return {
            'name': invoice.customer.name,
            'address': invoice.customer.address,
            'country': invoice.customer.country,
            'country_name': invoice.customer.get_country_display(),
            'email': invoice.customer.email,
            'postal': invoice.customer.postal,
            'phone_number': invoice.customer.phone_number,
            'bank_name': invoice.customer.bank_name,
            'bank_account': invoice.customer.bank_account,
        }

    def get_file(self, obj):
        if not obj.has_file():
            return None

        return reverse('invoice-pdf',
                       kwargs={'uuid': obj.uuid},
                       request=self.context['request'])


class InvoiceItemReportSerializer(serializers.ModelSerializer):
    invoice_number = serializers.ReadOnlyField(source='invoice.number')
    invoice_uuid = serializers.ReadOnlyField(source='invoice.uuid')
    invoice_year = serializers.ReadOnlyField(source='invoice.year')
    invoice_month = serializers.ReadOnlyField(source='invoice.month')
    invoice_date = serializers.ReadOnlyField(source='invoice.invoice_date')
    due_date = serializers.ReadOnlyField(source='invoice.due_date')
    customer_uuid = serializers.ReadOnlyField(source='invoice.customer.uuid')
    customer_name = serializers.ReadOnlyField(source='invoice.customer.name')

    class Meta(object):
        model = models.GenericInvoiceItem
        fields = (
            'customer_uuid', 'customer_name',
            'project_uuid', 'project_name',
            'invoice_uuid', 'invoice_number',
            'invoice_year', 'invoice_month',
            'invoice_date', 'due_date',
            'invoice_price', 'invoice_tax', 'invoice_total',
            'name', 'article_code', 'product_code',
            'price', 'tax', 'total', 'unit_price', 'unit',
            'start', 'end',
        )<commit_msg>Skip invoice items with zero total in invoice serializer [WAL-2474]<commit_after>from __future__ import unicode_literals

import datetime
from django.conf import settings
from rest_framework import serializers
from rest_framework.reverse import reverse

from waldur_core.core import serializers as core_serializers
from waldur_core.core import utils as core_utils
from waldur_mastermind.common.utils import quantize_price

from . import models, utils


class InvoiceItemSerializer(serializers.HyperlinkedModelSerializer):
    tax = serializers.DecimalField(max_digits=15, decimal_places=7)
    total = serializers.DecimalField(max_digits=15, decimal_places=7)
    factor = serializers.ReadOnlyField(source='get_factor')

    scope_type = serializers.SerializerMethodField()
    scope_uuid = serializers.SerializerMethodField()

    class Meta(object):
        model = models.InvoiceItem
        fields = ('name', 'price', 'tax', 'total', 'unit_price', 'unit', 'factor',
                  'start', 'end', 'product_code', 'article_code', 'project_name', 'project_uuid',
                  'scope_type', 'scope_uuid',)

    def get_scope_type(self, item):
        # It should be implemented by inherited class
        return

    def get_scope_uuid(self, item):
        # It should be implemented by inherited class
        return


class GenericItemSerializer(InvoiceItemSerializer):
    details = serializers.JSONField()

    class Meta(InvoiceItemSerializer.Meta):
        model = models.GenericInvoiceItem
        fields = InvoiceItemSerializer.Meta.fields + ('quantity', 'details', 'usage_days',)

    def get_scope_type(self, item):
        try:
            return item.content_type.model_class().get_scope_type()
        except AttributeError:
            return None

    def get_scope_uuid(self, item):
        if item.scope:
            return item.scope.uuid.hex
        return item.details.get('scope_uuid')


class InvoiceSerializer(core_serializers.RestrictedSerializerMixin,
                        serializers.HyperlinkedModelSerializer):
    price = serializers.DecimalField(max_digits=15, decimal_places=7)
    tax = serializers.DecimalField(max_digits=15, decimal_places=7)
    total = serializers.DecimalField(max_digits=15, decimal_places=7)
    items = serializers.SerializerMethodField()
    issuer_details = serializers.SerializerMethodField()
    customer_details = serializers.SerializerMethodField()
    due_date = serializers.DateField()
    file = serializers.SerializerMethodField()

    class Meta(object):
        model = models.Invoice
        fields = (
            'url', 'uuid', 'number', 'customer', 'price', 'tax', 'total',
            'state', 'year', 'month', 'issuer_details', 'invoice_date', 'due_date',
            'customer', 'customer_details', 'items', 'file',
        )
        extra_kwargs = {
            'url': {'lookup_field': 'uuid'},
            'customer': {'lookup_field': 'uuid'},
        }

    def get_issuer_details(self, invoice):
        return settings.WALDUR_INVOICES['ISSUER_DETAILS']

    def get_customer_details(self, invoice):
        return {
            'name': invoice.customer.name,
            'address': invoice.customer.address,
            'country': invoice.customer.country,
            'country_name': invoice.customer.get_country_display(),
            'email': invoice.customer.email,
            'postal': invoice.customer.postal,
            'phone_number': invoice.customer.phone_number,
            'bank_name': invoice.customer.bank_name,
            'bank_account': invoice.customer.bank_account,
        }

    def get_file(self, obj):
        if not obj.has_file():
            return None

        return reverse('invoice-pdf',
                       kwargs={'uuid': obj.uuid},
                       request=self.context['request'])

    def get_items(self, invoice):
        items = utils.filter_invoice_items(invoice.items.all())
        serializer = GenericItemSerializer(items, many=True, context=self.context)
        return serializer.data


class InvoiceItemReportSerializer(serializers.ModelSerializer):
    invoice_number = serializers.ReadOnlyField(source='invoice.number')
    invoice_uuid = serializers.ReadOnlyField(source='invoice.uuid')
    invoice_year = serializers.ReadOnlyField(source='invoice.year')
    invoice_month = serializers.ReadOnlyField(source='invoice.month')
    invoice_date = serializers.ReadOnlyField(source='invoice.invoice_date')
    due_date = serializers.ReadOnlyField(source='invoice.due_date')
    customer_uuid = serializers.ReadOnlyField(source='invoice.customer.uuid')
    customer_name = serializers.ReadOnlyField(source='invoice.customer.name')

    class Meta(object):
        model = models.GenericInvoiceItem
        fields = (
            'customer_uuid', 'customer_name',
            'project_uuid', 'project_name',
            'invoice_uuid', 'invoice_number',
            'invoice_year', 'invoice_month',
            'invoice_date', 'due_date',
            'invoice_price', 'invoice_tax', 'invoice_total',
            'name', 'article_code', 'product_code',
            'price', 'tax', 'total', 'unit_price', 'unit',
            'start', 'end',
        )
{'fraction_non_alphanumeric': 0.10911069344148779, 'fraction_numerical': 0.0033633395983776833, 'mean_word_length': 3.208992506244796, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '405358', 'n_tokens_mistral': 2876, 'n_tokens_neox': 2792, 'n_words': 545}