예제 #1
0
    def _create_item(self, source, invoice, start, end):
        package = source

        product_code = package.template.product_code
        article_code = package.template.article_code

        if package.template.unit == common_mixins.UnitPriceMixin.Units.PER_DAY:
            price = package.template.price
        else:
            price = package.template.monthly_price

        start = invoices_models.adjust_invoice_items(invoice, source, start,
                                                     price,
                                                     package.template.unit)

        item = invoices_models.InvoiceItem.objects.create(
            scope=package,
            project=_get_project(package),
            unit_price=price or 0,
            unit=package.template.unit,
            product_code=product_code,
            article_code=article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=self.get_details(package))
        self.init_details(item)
예제 #2
0
    def _create_item(self, source, invoice, start, end):
        try:
            resource = marketplace_models.Resource.objects.get(scope=source)
            plan = resource.plan
            if not plan:
                logger.warning(
                    'Skipping VMware item invoice creation because '
                    'billing plan is not defined for resource. '
                    'Resource ID: %s',
                    resource.id,
                )
                return
        except marketplace_models.Resource.DoesNotExist:
            logger.warning(
                'Skipping VMware item invoice creation because '
                'marketplace resource is not available for VMware resource. '
                'Resource ID: %s',
                source.id,
            )
            return

        components_map = {
            plan_component.component.type: plan_component.price
            for plan_component in plan.components.all()
        }

        missing_components = {'cpu', 'ram', 'disk'} - set(
            components_map.keys())
        if missing_components:
            logger.warning(
                'Skipping VMware item invoice creation because plan components are missing. '
                'Plan ID: %s. Missing components: %s',
                plan.id,
                ', '.join(missing_components),
            )
            return

        cores_price = components_map['cpu'] * source.cores
        ram_price = components_map['ram'] * mb_to_gb(source.ram)
        disk_price = components_map['disk'] * mb_to_gb(source.total_disk)
        total_price = cores_price + ram_price + disk_price

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

        details = self.get_details(source)
        item = invoices_models.InvoiceItem.objects.create(
            scope=source,
            project=_get_project(source),
            unit_price=total_price,
            unit=plan.unit,
            product_code=plan.product_code,
            article_code=plan.article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
        )
        self.init_details(item)
예제 #3
0
    def _create_item(self, source, invoice, start, end):
        package = source
        overlapping_item = utils.get_openstack_items().filter(
            invoice=invoice,
            end__day=start.day,
            details__contains=package.tenant.name,
        ).order_by('-unit_price').first()

        daily_price = package.template.price
        product_code = package.template.product_code
        article_code = package.template.article_code
        if overlapping_item:
            """
            Notes:
            |- date -| - used during the date
            |- **** -| - used during the day
            |- ---- -| - was requested to use in the current day but will be moved to next or previous one.
            |-***?---| - was used for a half day and '?' stands for a conflict.

            If there is an item that overlaps with current one as shown below:
            |--03.01.2017-|-********-|-***?---|
                                     |----?**-|-06.01.2017-|-******-|
            we have to make next steps:
            1) If item is more expensive -> use it for price calculation
                and register new package starting from next day [-06.01.2017-]
            |--03.01.2017-|-********-|-*****-|
                                     |-------|-06.01.2017-|-******-|

            2) If old package item is more expensive and it is the end of the month
            extend package usage till the end of the day and set current package end date to start date,
            so that usage days is 0 but it is still registered in the invoice.
            |--29.01.2017-|-********-|-***31.01.2017***-|
                                     |----31.01.2017----|

            3) If item is cheaper do exactly the opposite and shift its end date to yesterday,
            so new package will be registered today
            |--03.01.2017-|-********-|-------|
                                     |-*****-|-06.01.2017-|-******-|
            """
            if overlapping_item.unit_price > daily_price:
                if overlapping_item.end.day == invoices_utils.get_current_month_end().day:
                    utils.extend_to_the_end_of_the_day(overlapping_item)
                    end = start
                else:
                    start = start + timezone.timedelta(days=1)
            else:
                utils.shift_backward(overlapping_item)

        invoices_models.GenericInvoiceItem.objects.create(
            scope=package,
            project=_get_project(package),
            unit_price=daily_price,
            unit=invoices_models.GenericInvoiceItem.Units.PER_DAY,
            product_code=product_code,
            article_code=article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=self.get_details(package))
예제 #4
0
def get_issue_scopes(issue):
    result = set()
    if issue.resource:
        project = _get_project(issue.resource)
        result.add(issue.resource)
        result.add(project)
        result.add(project.customer)
    if issue.project:
        result.add(issue.project)
        result.add(issue.customer)
    if issue.customer:
        result.add(issue.customer)
    return result
def set_invoice_item_project(apps, schema_editor):
    OpenStackItem = apps.get_model('invoices', 'OpenStackItem')
    OfferingItem = apps.get_model('invoices', 'OfferingItem')

    for item in OpenStackItem.objects.all().exclude(package__isnull=True):
        project = _get_project(item.package)
        item.project_name = project.name
        item.project_uuid = project.uuid.hex
        item.save(update_fields=['project_name', 'project_uuid'])

    for item in OfferingItem.objects.all().exclude(offering__isnull=True):
        item.project_name = item.offering.project.name
        item.project_uuid = item.offering.project.uuid.hex
        item.save(update_fields=['project_name', 'project_uuid'])
예제 #6
0
def get_issue_scopes(issue):
    result = set()
    if issue.resource:
        try:
            project = _get_project(issue.resource)
            result.add(project)
            result.add(project.customer)
        except Project.DoesNotExist:
            # Project was deleted, soft-deleted projects will be handled below
            pass
        result.add(issue.resource)
    if issue.project_id:
        project = Project.all_objects.get(
            id=issue.project_id)  # handle soft-deleted projects
        result.add(project)
        result.add(issue.customer)
    if issue.customer:
        result.add(issue.customer)
    return result
예제 #7
0
def check_project_end_date(obj):
    from waldur_core.structure import permissions

    project = permissions._get_project(obj)
    if project.is_expired:
        raise ValidationError(_('Project \'%s\' is expired.') % project)