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)
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)
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))
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'])
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
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)