class SoftwareCategory(Named, CreatableFromString): """The category of the licensed software""" asset_type = models.PositiveSmallIntegerField(choices=AssetType()) @classmethod def create_from_string(cls, asset_type, s): return cls(asset_type=asset_type, name=s) @property def licences(self): """Iterate over licences.""" for licence in self.licence_set.all(): yield licence
def clean(self, *args, **kwargs): result = super(XlsColumnChoiceForm, self).clean(*args, **kwargs) if self.update: return result matched = set(result.values()) - {''} Model = get_model_by_name(self.model_reflected) required = { field.name for field in Model._meta.fields if not (field.blank or field.default != NOT_PROVIDED or field.choices == AssetType() or field.name in {'rght', 'tree_id', 'lft', 'level'}) } missing = required - matched if missing: raise forms.ValidationError( _('Missing fields: %s' % ', '.join(missing))) return result
class XlsUploadForm(forms.Form): """The first step for uploading the XLS file for asset bulk update.""" model = ModelChoiceField() file = DataUploadField() asset_type = forms.ChoiceField(choices=AssetType())
class Support( HistoryMixin, EditorTrackable, Named.NonUnique, models_assets.SupportAndAsset, SoftDeletable, SavingUser, TimeTrackable, WithConcurrentGetOrCreate, ): contract_id = models.CharField(max_length=50, blank=False) description = models.CharField(max_length=100, blank=True) attachments = models.ManyToManyField(models_assets.Attachment, null=True, blank=True) price = models.DecimalField( max_digits=10, decimal_places=2, default=0, null=True, blank=True, ) date_from = models.DateField(null=True, blank=True) date_to = models.DateField(null=False, blank=False) escalation_path = models.CharField(max_length=200, blank=True) contract_terms = models.CharField(max_length=200, blank=True) additional_notes = models.CharField(max_length=200, blank=True) sla_type = models.CharField(max_length=200, blank=True) asset_type = models.PositiveSmallIntegerField(choices=AssetType()) status = models.PositiveSmallIntegerField( default=SupportStatus.new.id, verbose_name=_("status"), choices=SupportStatus(), null=False, blank=False, ) producer = models.CharField(max_length=100, blank=True) supplier = models.CharField(max_length=100, blank=True) serial_no = models.CharField(max_length=100, blank=True) invoice_no = models.CharField(max_length=100, blank=True, db_index=True) invoice_date = models.DateField( null=True, blank=True, verbose_name=_('Invoice date'), ) period_in_months = models.IntegerField(null=True, blank=True) property_of = models.ForeignKey( AssetOwner, on_delete=models.PROTECT, null=True, blank=True, ) support_type = models.ForeignKey( SupportType, on_delete=models.PROTECT, blank=True, default=None, null=True, ) assets = models.ManyToManyField(Asset, related_name='supports') def __init__(self, *args, **kwargs): self.saving_user = None super(Support, self).__init__(*args, **kwargs) @property def url(self): return reverse('edit_support', kwargs={ 'support_id': self.id, }) def get_natural_end_support(self): return naturaltime(datetime(*(self.date_to.timetuple()[:6])))
class Licence( HistoryMixin, LicenseAndAsset, MPTTModel, TimeTrackable, WithConcurrentGetOrCreate, WithForm, SavingUser, ): """A set of licences for a single software with a single expiration date""" manufacturer = models.ForeignKey( AssetManufacturer, on_delete=models.PROTECT, blank=True, null=True, ) licence_type = models.ForeignKey( LicenceType, on_delete=models.PROTECT, ) property_of = models.ForeignKey( AssetOwner, on_delete=models.PROTECT, null=True, ) software_category = models.ForeignKey( SoftwareCategory, on_delete=models.PROTECT, ) number_bought = models.IntegerField( verbose_name=_('Number of purchased items'), ) sn = models.TextField( verbose_name=_('SN / Key'), null=True, blank=True, ) parent = TreeForeignKey( 'self', null=True, blank=True, related_name='children', verbose_name=_('Parent licence'), ) niw = models.CharField( max_length=200, verbose_name=_('Inventory number'), null=False, unique=True, default='N/A', ) invoice_date = models.DateField( verbose_name=_('Invoice date'), null=True, blank=True, ) valid_thru = models.DateField( null=True, blank=True, help_text="Leave blank if this licence is perpetual", ) order_no = models.CharField(max_length=50, null=True, blank=True) price = models.DecimalField( max_digits=10, decimal_places=2, default=0, null=True, blank=True, ) accounting_id = models.CharField( max_length=200, null=True, blank=True, help_text=_('Any value to help your accounting department ' 'identify this licence'), ) asset_type = models.PositiveSmallIntegerField( choices=AssetType(), verbose_name=_('Type'), ) assets = models.ManyToManyField( Asset, verbose_name=_('Assigned Assets'), ) users = models.ManyToManyField(User) attachments = models.ManyToManyField(Attachment, null=True, blank=True) provider = models.CharField(max_length=100, null=True, blank=True) invoice_no = models.CharField(max_length=128, db_index=True, null=True, blank=True) remarks = models.CharField( verbose_name=_('Additional remarks'), max_length=1024, null=True, blank=True, default=None, ) license_details = models.CharField( verbose_name=_('License details'), max_length=1024, blank=True, default='', ) service_name = models.ForeignKey(Service, null=True, blank=True) budget_info = models.ForeignKey( BudgetInfo, blank=True, default=None, null=True, on_delete=models.PROTECT, ) _used = None def __unicode__(self): return "{} x {} - {}".format( self.number_bought, self.software_category.name, self.invoice_date, ) @property def url(self): return reverse('edit_licence', kwargs={ 'licence_id': self.id, }) @property def used(self): if self._used is not None: return self._used return self.assets.count() + self.users.count() @used.setter def used(self, value): self._used = value