<commit_before>import decimal

from django.conf import settings

from waldur_mastermind.invoices.registrators import BaseRegistrator
from waldur_mastermind.invoices import models as invoices_models
from waldur_mastermind.marketplace_openstack import PACKAGE_TYPE, CORES_TYPE, RAM_TYPE, STORAGE_TYPE

from waldur_mastermind.marketplace import models
from waldur_mastermind.common.utils import mb_to_gb


class MarketplaceItemRegistrator(BaseRegistrator):
    def get_customer(self, source):
        return source.project.customer

    def get_sources(self, customer):
        if not settings.WALDUR_MARKETPLACE_OPENSTACK['BILLING_ENABLED']:
            return models.Resource.objects.none()

        return models.Resource.objects.filter(
            project__customer=customer,
            offering__type=PACKAGE_TYPE
        ).exclude(state__in=[
            models.Resource.States.CREATING,
            models.Resource.States.TERMINATED
        ])

    def _create_item(self, source, invoice, start, end):
        from waldur_mastermind.marketplace import plugins

        details = self.get_details(source)
        builtin_components = plugins.manager.get_components(source.offering.type)
        component_factors = {c.type: c.factor for c in builtin_components}
        unit_price = sum(
            decimal.Decimal(source.limits.get(component.component.type, 0)) * component.price /
            decimal.Decimal(component_factors.get(component.component.type, 1))
            for component in source.plan.components.all()
        )

        start = invoices_models.adjust_invoice_items(
            invoice, source, start, unit_price, source.plan.unit)

        item = invoices_models.InvoiceItem.objects.create(
            scope=source,
            project=source.project,
            unit_price=unit_price,
            unit=source.plan.unit,
            product_code=source.plan.product_code,
            article_code=source.plan.article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
        )
        self.init_details(item)

    def format_storage_description(self, source):
        if STORAGE_TYPE in source.limits:
            return '{disk} GB storage'.format(
                disk=int(mb_to_gb(source.limits.get(STORAGE_TYPE, 0)))
            )
        else:
            parts = []
            for (k, v) in source.limits.items():
                if k.startswith('gigabytes_'):
                    parts.append('{size} GB {type} storage'.format(
                        size=int(mb_to_gb(v)),
                        type=k.replace('gigabytes_', '')
                    ))
            return ' - '.join(parts)

    def get_name(self, source):
        return '{resource} ({offering} / VPC {cores} CPU - {ram} GB RAM - {storage})'.format(
            resource=source.name,
            offering=source.offering.name,
            cores=source.limits.get(CORES_TYPE),
            ram=int(mb_to_gb(source.limits.get(RAM_TYPE, 0))),
            storage=self.format_storage_description(source),
        )<commit_msg>Skip zero volume types in invoice item description.<commit_after>import decimal

from django.conf import settings

from waldur_mastermind.invoices.registrators import BaseRegistrator
from waldur_mastermind.invoices import models as invoices_models
from waldur_mastermind.marketplace_openstack import PACKAGE_TYPE, CORES_TYPE, RAM_TYPE, STORAGE_TYPE

from waldur_mastermind.marketplace import models
from waldur_mastermind.common.utils import mb_to_gb


class MarketplaceItemRegistrator(BaseRegistrator):
    def get_customer(self, source):
        return source.project.customer

    def get_sources(self, customer):
        if not settings.WALDUR_MARKETPLACE_OPENSTACK['BILLING_ENABLED']:
            return models.Resource.objects.none()

        return models.Resource.objects.filter(
            project__customer=customer,
            offering__type=PACKAGE_TYPE
        ).exclude(state__in=[
            models.Resource.States.CREATING,
            models.Resource.States.TERMINATED
        ])

    def _create_item(self, source, invoice, start, end):
        from waldur_mastermind.marketplace import plugins

        details = self.get_details(source)
        builtin_components = plugins.manager.get_components(source.offering.type)
        component_factors = {c.type: c.factor for c in builtin_components}
        unit_price = sum(
            decimal.Decimal(source.limits.get(component.component.type, 0)) * component.price /
            decimal.Decimal(component_factors.get(component.component.type, 1))
            for component in source.plan.components.all()
        )

        start = invoices_models.adjust_invoice_items(
            invoice, source, start, unit_price, source.plan.unit)

        item = invoices_models.InvoiceItem.objects.create(
            scope=source,
            project=source.project,
            unit_price=unit_price,
            unit=source.plan.unit,
            product_code=source.plan.product_code,
            article_code=source.plan.article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
        )
        self.init_details(item)

    def format_storage_description(self, source):
        if STORAGE_TYPE in source.limits:
            return '{disk} GB storage'.format(
                disk=int(mb_to_gb(source.limits.get(STORAGE_TYPE, 0)))
            )
        else:
            parts = []
            for (k, v) in source.limits.items():
                if k.startswith('gigabytes_') and v:
                    parts.append('{size} GB {type} storage'.format(
                        size=int(mb_to_gb(v)),
                        type=k.replace('gigabytes_', '')
                    ))
            return ' - '.join(parts)

    def get_name(self, source):
        return '{resource} ({offering} / VPC {cores} CPU - {ram} GB RAM - {storage})'.format(
            resource=source.name,
            offering=source.offering.name,
            cores=source.limits.get(CORES_TYPE),
            ram=int(mb_to_gb(source.limits.get(RAM_TYPE, 0))),
            storage=self.format_storage_description(source),
        )
{'fraction_non_alphanumeric': 0.09250321750321751, 'fraction_numerical': 0.001287001287001287, 'mean_word_length': 2.3880108991825613, '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': '6645349', 'n_tokens_mistral': 1798, 'n_tokens_neox': 1747, 'n_words': 317}