Ejemplo n.º 1
0
def create_usage(cluster):
    try:
        resource = marketplace_models.Resource.objects.get(scope=cluster)
    except django_exceptions.ObjectDoesNotExist:
        logger.debug(
            'Skipping node usage synchronization because this '
            'marketplace.Resource does not exist.'
            'Cluster ID: %s',
            cluster.id,
        )
        return

    date = datetime.date.today()
    usage = cluster.node_set.filter(
        state=core_models.StateMixin.States.OK).count()

    for component in manager.get_components(PLUGIN_NAME):
        try:
            offering_component = marketplace_models.OfferingComponent.objects.get(
                offering=resource.offering, type=component.type)
            plan_period = (marketplace_models.ResourcePlanPeriod.objects.
                           filter(Q(start__lte=date) | Q(start__isnull=True)).
                           filter(Q(end__gt=date) | Q(end__isnull=True)).get(
                               resource=resource))

            try:
                component_usage = marketplace_models.ComponentUsage.objects.get(
                    resource=resource,
                    component=offering_component,
                    billing_period=month_start(date),
                    plan_period=plan_period,
                )
                component_usage.usage = max(usage, component_usage.usage)
                component_usage.save()
            except django_exceptions.ObjectDoesNotExist:
                marketplace_models.ComponentUsage.objects.create(
                    resource=resource,
                    component=offering_component,
                    usage=usage,
                    date=date,
                    billing_period=month_start(date),
                    plan_period=plan_period,
                )

        except marketplace_models.OfferingComponent.DoesNotExist:
            logger.warning(
                'Skipping node usage synchronization because this '
                'marketplace.OfferingComponent does not exist.'
                'Cluster ID: %s',
                cluster.id,
            )
        except marketplace_models.ResourcePlanPeriod.DoesNotExist:
            logger.warning(
                'Skipping node usage synchronization because this '
                'marketplace.ResourcePlanPeriod does not exist.'
                'Cluster ID: %s',
                cluster.id,
            )
Ejemplo n.º 2
0
    def validate(self, attrs):
        resource = attrs['resource']
        date = attrs['date']
        plan = resource.plan

        if resource.state == models.Resource.States.TERMINATED:
            raise rf_exceptions.ValidationError({
                'resource': _('Resource is terminated.')
            })

        if not plan:
            raise rf_exceptions.ValidationError({
                'resource': _('Resource does not have billing plan.')
            })

        if date > datetime.date.today():
            raise rf_exceptions.ValidationError({'date': _('Invalid date value.')})

        if invoices_models.Invoice.objects.filter(customer=resource.project.customer,
                                                  year=date.year,
                                                  month=date.month). \
                filter(state__in=[invoices_models.Invoice.States.CREATED,
                                  invoices_models.Invoice.States.PAID]).exists():
            # If an invoice exists, and invoice state is created or paid then a billing period is closed.
            raise rf_exceptions.ValidationError({
                'date':
                    _('Cannot update usage information. Billing period is closed.')
            })

        if plan.unit == UnitPriceMixin.Units.PER_MONTH:
            attrs['date'] = core_utils.month_start(date)

        if plan.unit == UnitPriceMixin.Units.PER_HALF_MONTH:
            if date.day < 16:
                attrs['date'] = core_utils.month_start(date)
            else:
                attrs['date'] = datetime.date(year=date.year, month=date.month, day=16)

        for usage in attrs['usages']:
            component_type = usage['type']
            offering = resource.plan.offering
            try:
                component = models.OfferingComponent.objects.get(
                    offering=offering,
                    type=component_type,
                    billing_type=models.OfferingComponent.BillingTypes.USAGE,
                )
                usage['component'] = component
            except models.OfferingComponent.DoesNotExist:
                raise rf_exceptions.ValidationError(_('Component "%s" is not found.') % component_type)

        return attrs
Ejemplo n.º 3
0
def create_monthly_invoices():
    """
    - For every customer change state of the invoices for previous months from "pending" to "billed"
      and freeze their items.
    - Create new invoice for every customer in current month if not created yet.
    """
    date = timezone.now()

    old_invoices = models.Invoice.objects.filter(
        Q(state=models.Invoice.States.PENDING, year__lt=date.year)
        | Q(state=models.Invoice.States.PENDING, year=date.year, month__lt=date.month)
    )
    for invoice in old_invoices:
        invoice.set_created()

    customers = structure_models.Customer.objects.all()
    if settings.WALDUR_CORE['ENABLE_ACCOUNTING_START_DATE']:
        customers = customers.filter(accounting_start_date__lt=timezone.now())

    for customer in customers.iterator():
        registrators.RegistrationManager.get_or_create_invoice(
            customer, core_utils.month_start(date)
        )

    if settings.WALDUR_INVOICES['INVOICE_REPORTING']['ENABLE']:
        send_invoice_report.delay()

    if settings.WALDUR_INVOICES['SEND_CUSTOMER_INVOICES']:
        chain(create_pdf_for_new_invoices.si(), send_new_invoices_notification.si())()
    else:
        create_pdf_for_new_invoices.delay()
Ejemplo n.º 4
0
 def test_handler(self):
     component = factories.OfferingComponentFactory(
         offering=self.resource.offering,
         billing_type=models.OfferingComponent.BillingTypes.USAGE,
         type='storage',
     )
     self._create_item()
     usage = factories.ComponentUsageFactory(
         resource=self.resource,
         billing_period=core_utils.month_start(timezone.now()),
         component=component,
     )
     self.client.force_authenticate(self.fixture.staff)
     result = self.client.get(self.url, {
         'start': '2020-03',
         'end': '2020-03'
     })
     self.assertEqual(
         result.data,
         [{
             'period': '2020-03',
             'components': {
                 'cpu': 1,
                 usage.component.type: usage.usage
             },
         }],
     )
Ejemplo n.º 5
0
    def test_event_log_is_created_if_component_usage_has_been_created(
            self, mock_logger):
        self.client.force_authenticate(self.fixture.staff)
        usage_data = self.get_usage_data()
        response = self.client.post(
            '/api/marketplace-component-usages/set_usage/', usage_data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        mock_logger.info.assert_called_with(
            'Usage has been created for %s, component: ram, value: 5' %
            self.resource)

        date = timezone.now()
        billing_period = core_utils.month_start(date)
        component_usage = models.ComponentUsage.objects.get(
            resource=self.resource,
            component=self.offering_component,
            date=date,
            billing_period=billing_period,
        )

        logging_models.Event.objects.get(
            message='Marketplace component usage %s has been created.' %
            component_usage.uuid)
        usage_data['usages'][0]['amount'] = 8
        self.client.post('/api/marketplace-component-usages/set_usage/',
                         usage_data)

        logging_models.Event.objects.get(
            message='Marketplace component usage %s has been updated.' %
            component_usage.uuid)
Ejemplo n.º 6
0
    def test_event_log_creates_if_component_usage_has_been_created(
            self, mock_logger):
        self.client.force_authenticate(self.fixture.staff)
        usage_data = self.get_usage_data()
        response = self.client.post(
            '/api/marketplace-component-usages/set_usage/', usage_data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        mock_logger.info.assert_called_once_with(
            'Usage has been created. Data: {\'plan_period\': \'%s\','
            ' \'usages\': [{\'type\': \'cpu\', \'amount\': 5, \'description\': \'\'}]}.'
            % self.plan_period.uuid.hex)

        date = timezone.now()
        billing_period = core_utils.month_start(date)
        component_usage = models.ComponentUsage.objects.get(
            resource=self.resource,
            component=self.offering_component,
            date=date,
            billing_period=billing_period,
        )

        logging_models.Event.objects.get(
            message='Marketplace component usage %s has been created.' %
            component_usage.uuid)
        usage_data['usages'][0]['amount'] = 8
        self.client.post('/api/marketplace-component-usages/set_usage/',
                         usage_data)

        logging_models.Event.objects.get(
            message='Marketplace component usage %s has been updated.' %
            component_usage.uuid)
Ejemplo n.º 7
0
class ResourcePlanPeriodFactory(factory.DjangoModelFactory):
    class Meta:
        model = models.ResourcePlanPeriod

    resource = factory.SubFactory(ResourceFactory)
    plan = factory.SubFactory(PlanFactory)
    start = core_utils.month_start(timezone.now())
Ejemplo n.º 8
0
def component_usage_register(component_usage):
    from waldur_mastermind.slurm_invoices.registrators import AllocationRegistrator

    plan_period = component_usage.plan_period
    if not plan_period:
        logger.warning(
            'Skipping processing of component usage with ID %s because '
            'plan period is not defined.',
            component_usage.id,
        )
        return

    try:
        plan = plan_period.plan
        plan_component = plan.components.get(component=component_usage.component)
        allocation = component_usage.resource.scope
        customer = allocation.project.customer
        invoice, created = registrators.RegistrationManager.get_or_create_invoice(
            customer, component_usage.date
        )

        details = AllocationRegistrator().get_component_details(
            allocation, plan_component
        )
        details['plan_period_id'] = plan_period.id
        offering_component = plan_component.component

        month_start = core_utils.month_start(component_usage.date)
        month_end = core_utils.month_end(component_usage.date)

        start = (
            month_start
            if not component_usage.plan_period.start
            else max(component_usage.plan_period.start, month_start)
        )
        end = (
            month_end
            if not component_usage.plan_period.end
            else min(component_usage.plan_period.end, month_end)
        )

        invoice_models.InvoiceItem.objects.create(
            content_type=ContentType.objects.get_for_model(allocation),
            object_id=allocation.id,
            project=allocation.project,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
            unit_price=plan_component.price,
            quantity=component_usage.usage,
            unit=common_mixins.UnitPriceMixin.Units.QUANTITY,
            product_code=offering_component.product_code or plan.product_code,
            article_code=offering_component.article_code or plan.article_code,
        )

    except marketplace_models.PlanComponent.DoesNotExist:
        logger.warning(
            'Plan component for usage component %s is not found.', component_usage.id
        )
Ejemplo n.º 9
0
 def test_set_recurring_to_false_for_other_usages_in_this_period(self):
     self.client.force_authenticate(self.fixture.staff)
     payload = self.get_usage_data()
     payload['usages'][0]['recurring'] = True
     response = self.client.post(
         '/api/marketplace-component-usages/set_usage/', payload)
     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
     date = timezone.now()
     billing_period = core_utils.month_start(date)
     usage = models.ComponentUsage.objects.get(
         resource=self.resource,
         component=self.offering_component,
         date=date,
         billing_period=billing_period,
     )
     self.assertTrue(usage.recurring)
     new_plan_period = models.ResourcePlanPeriod.objects.create(
         resource=self.plan_period.resource,
         plan=self.plan_period.plan,
     )
     self.plan_period = new_plan_period
     payload = self.get_usage_data()
     response = self.client.post(
         '/api/marketplace-component-usages/set_usage/', payload)
     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
     usage.refresh_from_db()
     self.assertFalse(usage.recurring)
Ejemplo n.º 10
0
def get_info_about_missing_usage_reports():
    now = timezone.now()
    billing_period = core_utils.month_start(now)

    offering_ids = models.OfferingComponent.objects.filter(
        billing_type=models.OfferingComponent.BillingTypes.USAGE
    ).values_list('offering_id', flat=True)
    resource_with_usages = models.ComponentUsage.objects.filter(
        billing_period=billing_period
    ).values_list('resource', flat=True)
    resources_without_usages = models.Resource.objects.filter(
        state=models.Resource.States.OK, offering_id__in=offering_ids
    ).exclude(id__in=resource_with_usages)
    result = []

    for resource in resources_without_usages:
        rows = list(
            filter(lambda x: x['customer'] == resource.offering.customer, result)
        )
        if rows:
            rows[0]['resources'].append(resource)
        else:
            result.append(
                {'customer': resource.offering.customer, 'resources': [resource],}
            )

    return result
Ejemplo n.º 11
0
 def test_item_details(self):
     component = factories.OfferingComponentFactory(
         offering=self.resource.offering,
         billing_type=models.OfferingComponent.BillingTypes.USAGE,
         type='storage',
     )
     usage = factories.ComponentUsageFactory(
         resource=self.resource,
         billing_period=core_utils.month_start(timezone.now()),
         component=component,
     )
     item = self._create_item()
     self.assertEqual(
         item.details,
         {
             'limits': self.resource.limits,
             'usages': {
                 usage.component.type: usage.usage
             },
             'scope_uuid': item.scope.uuid.hex,
             'offering_name': self.offering.name,
             'offering_type': PACKAGE_TYPE,
             'offering_uuid': self.offering.uuid.hex,
         },
     )
Ejemplo n.º 12
0
def create_recurring_usage_if_invoice_has_been_created(
    sender, instance, created=False, **kwargs
):
    if not created:
        return

    invoice = instance

    now = timezone.now()
    prev_month = (now.replace(day=1) - datetime.timedelta(days=1)).date()
    prev_month_start = prev_month.replace(day=1)
    usages = marketplace_models.ComponentUsage.objects.filter(
        resource__project__customer=invoice.customer,
        recurring=True,
        billing_period__gte=prev_month_start,
    ).exclude(resource__state=marketplace_models.Resource.States.TERMINATED)

    if not usages:
        return

    for usage in usages:
        marketplace_models.ComponentUsage.objects.create(
            resource=usage.resource,
            component=usage.component,
            usage=usage.usage,
            description=usage.description,
            date=now,
            plan_period=usage.plan_period,
            recurring=usage.recurring,
            billing_period=core_utils.month_start(now),
        )
Ejemplo n.º 13
0
    def on_resource_post_save(cls, sender, instance, created=False, **kwargs):
        resource = instance
        if resource.offering.type != cls.plugin_name:
            return

        if created:
            return

        if (
            resource.state == ResourceStates.OK
            and resource.tracker.previous('state') == ResourceStates.CREATING
        ):
            registrators.RegistrationManager.register(
                resource, timezone.now(), order_type=OrderTypes.CREATE
            )

        if (
            resource.state == ResourceStates.TERMINATED
            and instance.tracker.previous('state') == ResourceStates.TERMINATING
        ):
            registrators.RegistrationManager.terminate(resource, timezone.now())

        if resource.tracker.has_changed('plan_id'):
            registrators.RegistrationManager.terminate(resource, timezone.now())
            registrators.RegistrationManager.register(
                resource, timezone.now(), order_type=OrderTypes.UPDATE
            )

        if resource.tracker.has_changed('limits'):
            today = timezone.now()
            invoice, _ = registrators.RegistrationManager.get_or_create_invoice(
                resource.project.customer, core_utils.month_start(today)
            )
            valid_limits = set(
                resource.offering.components.filter(
                    billing_type=BillingTypes.LIMIT
                ).values_list('type', flat=True)
            )
            for component_type, new_quantity in resource.limits.items():
                if component_type not in valid_limits:
                    continue
                offering_component = resource.offering.components.get(
                    type=component_type
                )
                if (
                    offering_component.billing_type == BillingTypes.LIMIT
                    and offering_component.limit_period == LimitPeriods.TOTAL
                ):
                    cls.create_invoice_item_for_total_limit(
                        resource,
                        invoice,
                        component_type,
                        new_quantity,
                        offering_component,
                    )
                else:
                    cls.create_or_update_component_item(
                        resource, invoice, component_type, new_quantity
                    )
Ejemplo n.º 14
0
def component_usage_register(component_usage):
    from waldur_mastermind.support_invoices.registrators import OfferingRegistrator

    plan_period = component_usage.plan_period
    if not plan_period:
        logger.warning('Skipping processing of component usage with ID %s because '
                       'plan period is not defined.', component_usage.id)
        return
    plan = plan_period.plan

    try:
        plan_component = plan.components.get(component=component_usage.component)
        item = invoice_models.InvoiceItem.objects.get(scope=component_usage.resource.scope,
                                                      details__plan_period_id=plan_period.id,
                                                      details__plan_component_id=plan_component.id)
        item.quantity = component_usage.usage
        item.unit_price = plan_component.price
        item.save()
    except invoice_models.InvoiceItem.DoesNotExist:
        offering = component_usage.resource.scope
        customer = offering.project.customer
        invoice, created = registrators.RegistrationManager.get_or_create_invoice(customer, component_usage.date)

        details = OfferingRegistrator().get_component_details(offering, plan_component)
        details['plan_period_id'] = plan_period.id
        offering_component = plan_component.component

        month_start = core_utils.month_start(component_usage.date)
        month_end = core_utils.month_end(component_usage.date)

        start = month_start if not component_usage.plan_period.start else \
            max(component_usage.plan_period.start, month_start)
        end = month_end if not component_usage.plan_period.end else \
            min(component_usage.plan_period.end, month_end)

        invoice_models.InvoiceItem.objects.create(
            content_type=ContentType.objects.get_for_model(offering),
            object_id=offering.id,
            project=offering.project,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
            unit_price=plan_component.price,
            quantity=component_usage.usage,
            unit=common_mixins.UnitPriceMixin.Units.QUANTITY,
            product_code=offering_component.product_code or plan.product_code,
            article_code=offering_component.article_code or plan.article_code,
        )

    except marketplace_models.PlanComponent.DoesNotExist:
        logger.warning('Plan component for usage component %s is not found.', component_usage.id)
    except invoice_models.InvoiceItem.MultipleObjectsReturned:
        logger.warning('Skipping the invoice item unit price update '
                       'because multiple GenericInvoiceItem objects found. Scope: %s %s, date: %s.',
                       component_usage.resource.content_type,
                       component_usage.resource.object_id,
                       component_usage.date)
Ejemplo n.º 15
0
class ComponentUsageFactory(factory.DjangoModelFactory):
    class Meta:
        model = models.ComponentUsage

    resource = factory.SubFactory(ResourceFactory)
    component = factory.SubFactory(OfferingComponentFactory)
    usage = 1
    date = timezone.now()
    billing_period = core_utils.month_start(timezone.now())
Ejemplo n.º 16
0
def update_component_quota(sender, instance, created=False, **kwargs):
    if created:
        return

    if not set(instance.tracker.changed()) & COMPONENT_FIELDS:
        return

    allocation = instance

    try:
        resource = marketplace_models.Resource.objects.get(scope=allocation)
    except django_exceptions.ObjectDoesNotExist:
        return

    for component in manager.get_components(PLUGIN_NAME):
        usage = getattr(allocation, component.type + '_usage')
        limit = getattr(allocation, component.type + '_limit')

        try:
            offering_component = marketplace_models.OfferingComponent.objects.get(
                offering=resource.offering, type=component.type
            )
        except marketplace_models.OfferingComponent.DoesNotExist:
            logger.warning(
                'Skipping Allocation synchronization because this '
                'marketplace.OfferingComponent does not exist.'
                'Allocation ID: %s',
                allocation.id,
            )
        else:
            marketplace_models.ComponentQuota.objects.update_or_create(
                resource=resource,
                component=offering_component,
                defaults={'limit': limit, 'usage': usage},
            )
            try:
                plan_period = marketplace_models.ResourcePlanPeriod.objects.get(
                    resource=resource, end=None
                )
            except (ObjectDoesNotExist, MultipleObjectsReturned):
                logger.warning(
                    'Skipping component usage synchronization because valid'
                    'ResourcePlanPeriod is not found.'
                    'Allocation ID: %s',
                    allocation.id,
                )
            else:
                date = timezone.now()
                marketplace_models.ComponentUsage.objects.update_or_create(
                    resource=resource,
                    component=offering_component,
                    billing_period=month_start(date),
                    plan_period=plan_period,
                    defaults={'usage': usage, 'date': date},
                )
Ejemplo n.º 17
0
 def test_create_usage(self):
     response = self.submit_usage()
     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
     date = timezone.now()
     billing_period = core_utils.month_start(date)
     self.assertTrue(
         models.ComponentUsage.objects.filter(
             resource=self.resource,
             component=self.offering_component,
             date=date,
             billing_period=billing_period).exists())
Ejemplo n.º 18
0
def _create_historical_estimates(resource, configuration):
    """ Create consumption details and price estimates for past months.

        Usually we need to update historical values on resource import.
    """
    today = timezone.now()
    month_start = core_utils.month_start(today)
    while month_start > resource.created:
        month_start -= relativedelta(months=1)
        models.PriceEstimate.create_historical(
            resource, configuration, max(month_start, resource.created))
Ejemplo n.º 19
0
    def shift_backward(self):
        """
        Adjust old invoice item end field to the end of previous unit
        Adjust new invoice item field to the start of current unit.
        """
        end = self.old_item.end

        if self.old_item.unit != self.unit and self.unit == Units.PER_MONTH:
            start = core_utils.month_start(end)
        elif self.old_item.unit != self.unit and self.unit == Units.PER_HALF_MONTH:
            if end.day < 15:
                start = core_utils.month_start(end)
            else:
                start = end.replace(day=15)
        elif self.unit == Units.PER_HOUR:
            start = end.replace(minute=0, second=0)
        else:
            start = end.replace(hour=0, minute=0, second=0)

        end = start - timedelta(seconds=1)
        return start, end
Ejemplo n.º 20
0
    def test_total_amount_exceeds_total_limit(self):
        self.offering_component.limit_period = models.OfferingComponent.LimitPeriods.TOTAL
        self.offering_component.limit_amount = 7
        self.offering_component.save()

        models.ComponentUsage.objects.create(
            resource=self.resource,
            component=self.offering_component,
            date=core_utils.month_start(datetime.date.today()),
            usage=5,
        )
        response = self.submit_usage()
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Ejemplo n.º 21
0
 def handle(self, *args, **options):
     today = timezone.now()
     with transaction.atomic():
         # Delete current month price estimates
         models.PriceEstimate.objects.filter(month=today.month, year=today.year).delete()
         # Create new estimates for resources and ancestors
         for resource_model in CostTrackingRegister.registered_resources:
             for resource in resource_model.objects.all():
                 configuration = CostTrackingRegister.get_configuration(resource)
                 date = max(core_utils.month_start(today), resource.created)
                 models.PriceEstimate.create_historical(resource, configuration, date)
         # recalculate consumed estimate
         tasks.recalculate_estimate()
Ejemplo n.º 22
0
 def test_invoice_price_includes_usage_components(self):
     invoice = invoices_models.Invoice.objects.get(customer=self.allocation.service_project_link.project.customer)
     self.assertEqual(invoice.price, 0)
     marketplace_models.ComponentUsage.objects.create(
         resource=self.resource,
         component=self.resource.plan.components.first().component,
         usage=1,
         date=datetime.date.today(),
         billing_period=month_start(datetime.date.today()),
         plan_period=self.plan_period
     )
     invoice.refresh_from_db()
     self.assertEqual(invoice.price, 3)
Ejemplo n.º 23
0
 def test_item_details(self):
     sp = factories.ServiceProviderFactory(
         customer=self.resource.offering.customer)
     component = factories.OfferingComponentFactory(
         offering=self.resource.offering,
         billing_type=models.OfferingComponent.BillingTypes.LIMIT,
         type='storage',
     )
     factories.ComponentUsageFactory(
         resource=self.resource,
         billing_period=core_utils.month_start(timezone.now()),
         component=component,
     )
     item = self._create_items().first()
     self.assertDictEqual(
         item.details,
         {
             'resource_name':
             item.resource.name,
             'resource_uuid':
             item.resource.uuid.hex,
             'service_provider_name':
             self.resource.offering.customer.name,
             'service_provider_uuid':
             sp.uuid.hex,
             'offering_name':
             self.offering.name,
             'offering_type':
             TENANT_TYPE,
             'offering_uuid':
             self.offering.uuid.hex,
             'plan_name':
             self.resource.plan.name,
             'plan_uuid':
             self.resource.plan.uuid.hex,
             'plan_component_id':
             self.plan_component.id,
             'offering_component_type':
             self.plan_component.component.type,
             'offering_component_name':
             self.plan_component.component.name,
             'resource_limit_periods': [{
                 'end': '2020-03-31T23:59:59.999999+00:00',
                 'start': '2020-03-01T00:00:00+00:00',
                 'total': '31',
                 'quantity': 1,
                 'billing_periods': 31,
             }],
         },
     )
Ejemplo n.º 24
0
 def test_authenticated_user_can_submit_usage_via_api(self, role):
     self.client.force_authenticate(getattr(self.fixture, role))
     response = self.client.post(
         '/api/marketplace-component-usages/set_usage/',
         self.get_usage_data())
     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
     date = timezone.now()
     billing_period = core_utils.month_start(date)
     self.assertTrue(
         models.ComponentUsage.objects.filter(
             resource=self.resource,
             component=self.offering_component,
             date=date,
             billing_period=billing_period).exists())
Ejemplo n.º 25
0
 def _create_usage(self, date=None, **kwargs):
     date = date or datetime.date.today()
     plan_period = marketplace_models.ResourcePlanPeriod.objects. \
         filter(Q(start__lte=date) | Q(start__isnull=True)). \
         filter(Q(end__gt=date) | Q(end__isnull=True)). \
         get(resource=self.resource)
     option = dict(resource=self.resource,
                   component=self.fixture.offering_component_cpu,
                   usage=10,
                   date=date,
                   billing_period=core_utils.month_start(date),
                   plan_period=plan_period)
     option.update(kwargs)
     return marketplace_models.ComponentUsage.objects.create(**option)
Ejemplo n.º 26
0
 def test_plan_period_linking(self):
     response = self.submit_usage()
     self.assertEqual(response.status_code, status.HTTP_201_CREATED)
     date = timezone.now()
     billing_period = core_utils.month_start(date)
     usage = models.ComponentUsage.objects.get(
         resource=self.resource,
         component=self.offering_component,
         date=date,
         billing_period=billing_period)
     plan_period = models.ResourcePlanPeriod.objects.get(
         resource=self.resource,
         start=datetime.date(2017, 1, 10),
         end__isnull=True)
     self.assertEqual(usage.plan_period, plan_period)
Ejemplo n.º 27
0
    def validate_amount(self, resource, amount, date):
        if not self.limit_period or not self.limit_amount:
            return

        usages = ComponentUsage.objects.filter(resource=resource,
                                               component=self)

        if self.limit_period == OfferingComponent.LimitPeriods.MONTH:
            usages = usages.filter(date=core_utils.month_start(date))

        total = usages.aggregate(models.Sum('usage'))['usage__sum'] or 0

        if total + amount > self.limit_amount:
            raise rf_exceptions.ValidationError(
                _('Total amount exceeds exceeds limit. Total amount: %s, limit: %s.'
                  ) % (total + amount, self.limit_amount))
Ejemplo n.º 28
0
 def create(self, price_estimate):
     """ Take configuration from previous month, it it exists.
         Set last_update_time equals to the beginning of the month.
     """
     kwargs = {}
     try:
         previous_price_estimate = price_estimate.get_previous()
     except ObjectDoesNotExist:
         pass
     else:
         configuration = previous_price_estimate.consumption_details.configuration
         kwargs['configuration'] = configuration
     month_start = core_utils.month_start(
         datetime.date(price_estimate.year, price_estimate.month, 1))
     kwargs['last_update_time'] = month_start
     return super(ConsumptionDetailsQuerySet,
                  self).create(price_estimate=price_estimate, **kwargs)
Ejemplo n.º 29
0
 def get_common_data(self, start=None, end=None, quantity=100):
     now = timezone.now()
     if start is None:
         start = month_start(now)
     if end is None:
         end = month_end(now)
     return {
         'unit': 'sample-unit',
         'name': 'Fake invoice item',
         'measured_unit': 'sample-m-unit',
         'article_code': '',
         'unit_price': 2.0,
         'details': {},
         'quantity': quantity,
         'start': start.isoformat(),
         'end': end.isoformat(),
     }
Ejemplo n.º 30
0
def _create_slurm_usage(instance):
    allocation_usage = instance
    allocation = allocation_usage.allocation

    try:
        resource = marketplace_models.Resource.objects.get(scope=allocation)
    except django_exceptions.ObjectDoesNotExist:
        return

    date = datetime.date(year=allocation_usage.year,
                         month=allocation_usage.month,
                         day=1)

    for component in manager.get_components(PLUGIN_NAME):
        usage = getattr(allocation_usage, component.type + '_usage')

        try:
            plan_component = marketplace_models.OfferingComponent.objects.get(
                offering=resource.offering, type=component.type)
            plan_period = (marketplace_models.ResourcePlanPeriod.objects.
                           filter(Q(start__lte=date) | Q(start__isnull=True)).
                           filter(Q(end__gt=date) | Q(end__isnull=True)).get(
                               resource=resource))
            marketplace_models.ComponentUsage.objects.create(
                resource=resource,
                component=plan_component,
                usage=usage,
                date=date,
                billing_period=month_start(date),
                plan_period=plan_period,
            )
        except django_exceptions.ObjectDoesNotExist:
            logger.warning(
                'Skipping AllocationUsage synchronization because this '
                'marketplace.OfferingComponent does not exist.'
                'AllocationUsage ID: %s',
                allocation_usage.id,
            )
        except IntegrityError:
            logger.warning(
                'Skipping AllocationUsage synchronization because this marketplace.ComponentUsage exists.'
                'AllocationUsage ID: %s',
                allocation_usage.id,
                exc_info=True,
            )