class Track(models.Model): title = models.CharField(_("title"), max_length=300) audio_url = models.URLField(_("audio url"), unique=True, max_length=600) length = models.DecimalField(_("length"), max_digits=10, decimal_places=2, help_text=_("in seconds")) summary = models.TextField(_("summary"), null=True, blank=True) doc_id = models.CharField(_("NLI document ID"), max_length=100, unique=True, null=True, blank=True) bookmarks = TreeManyToManyField(Bookmark, related_name='tracks', blank=True) class Meta: verbose_name = _("track") verbose_name_plural = _("tracks") def __str__(self): return self.title def get_absolute_url(self): return reverse('audio:detail', args=[str(self.id)]) def length_str(self): return "{:01.0f}:{:02.0f}".format(*divmod(self.length, 60))
class Work(models.Model): work_category = TreeManyToManyField(WorkCategory, blank=True) sejour = models.ForeignKey(Sejour) work_name = models.CharField(max_length=50, default='Travail') heure = models.SmallIntegerField(default=1) minutes = models.SmallIntegerField(default=0) quantity = models.IntegerField(default=0)
class CategoryPost(models.Model): categories = TreeManyToManyField('Category', blank=True, related_name='posts', verbose_name=_('categorías')) class Meta: abstract = True
class Book(MPTTModel): parent = TreeForeignKey( 'self', null=True, blank=True, related_name='children', on_delete=models.CASCADE) name = models.CharField(max_length=50) fk = TreeForeignKey(Category, null=True, blank=True, related_name='books_fk') m2m = TreeManyToManyField(Category, null=True, blank=True, related_name='books_m2m')
class Movie(CreationModificationDateMixin): title = models.CharField(max_length=255) categories = TreeManyToManyField(Category) def __str__(self): return self.title class Meta: verbose_name_plural = 'movies'
def handle_model(self): self.model.add_to_class( 'feincms_navigation', TreeManyToManyField( Page, blank=True, symmetrical=False, help_text='Pages linked to in the navigation of this page.', limit_choices_to={'in_navigation': True}, related_name='fein_nav'))
class Book(MPTTModel): parent = TreeForeignKey( "self", null=True, blank=True, related_name="children", on_delete=models.CASCADE ) name = models.CharField(max_length=50) fk = TreeForeignKey( Category, null=True, blank=True, related_name="books_fk", on_delete=models.CASCADE, ) m2m = TreeManyToManyField(Category, blank=True, related_name="books_m2m")
class Category(MPTTModel): name = models.CharField(max_length=128, default=None, unique=True, db_index=True, verbose_name='Название') is_active = models.BooleanField(default=True, verbose_name='Активно') parent = TreeForeignKey('self', blank=True, null=True, default=None, on_delete=models.CASCADE, related_name='children', db_index=True, verbose_name='Родительская категория') groups = TreeManyToManyField('AttrGroup', through='AttrGroupInCategory', through_fields=('category', 'group'), related_name='categories') slug = models.SlugField(max_length=128, blank=True, null=True, default=None, unique=True) description = models.TextField(blank=True, null=True, default=None, verbose_name='Описание категории') image = models.ImageField(upload_to='category_images/', blank=True, null=True, verbose_name='Фото категории') sign = models.ImageField(upload_to='category_sign/', blank=True, null=True, verbose_name='Значек категории') class Meta: verbose_name = "Категория товаров" verbose_name_plural = "Категории товаров" def __str__(self): return self.name # def delete(self, *args, **kwargs): # # for prod in self.related_products.all(): # # prod.delete_attributes() # Product.objects.bulk_update([ # del_attrs_when_delcat_from_prod(product, self) # for product in Product.objects.filter( # related_categories__category_id=self.id).only('parameters', 'parameters_structure')], # ['parameters', 'parameters_structure']) # super().delete(*args, **kwargs) def save(self, *args, **kwargs): if not self.slug: self.slug = get_unique_slug(self, 'name', 'slug') super().save(*args, **kwargs) class MPTTMeta: level_attr = 'mptt_level' order_insertion_by = ['name'] @property def getlink(self): link = "<a href=%s>%s</a>" % (reverse('admin:products_category_change', args=(self.id,)), self.name) return mark_safe(link) @property def have_children(self): return self.children.filter(is_active=True).exists() @property def children_category(self): return self.children.filter(is_active=True)
class Shoe(Product): categories = TreeManyToManyField(ShoeCategory, verbose_name='Catégories') class Meta: verbose_name = 'Chaussures' def get_entrees(self): return ShoeEntry.objects def get_sorties(self): return ShoeOutput.objects def get_absolute_url(self): return reverse('shoes:detail', kwargs={'pk': self.pk})
class News(Base): """ Модель новости """ title = models.CharField(max_length=255, verbose_name=_('Title')) slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug')) date = models.DateField(verbose_name=_('Date'), blank=False) sections = TreeManyToManyField(Section, verbose_name=_('Sections')) image = ImageField(upload_to='news', verbose_name=_('Image'), blank=True) annotation = models.TextField(blank=True, verbose_name=_('Annotation')) text = RichTextField(blank=True, verbose_name=_('Text')) comments = models.BooleanField(default=False, verbose_name=_('Comments')) metatitle = models.CharField(max_length=2000, blank=True, verbose_name=_('Title')) keywords = models.CharField(max_length=2000, blank=True, verbose_name=_('Keywords')) description = models.CharField(max_length=2000, blank=True, verbose_name=_('Description')) def get_absolute_url(self): return reverse('midnight_news:news_detail', kwargs={ 'section_slug': self.sections.all()[0].slug, 'slug': self.slug }) def __str__(self): return self.title class Meta: verbose_name = _('NewsItem') verbose_name_plural = _('News')
class Page(models.Model): THUMB_HEIGHT = 100 book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='pages') ordinal = models.PositiveIntegerField() img_id = models.CharField(max_length=100, unique=True) height = models.PositiveIntegerField() width = models.PositiveIntegerField() bookmarks = TreeManyToManyField(Bookmark, blank=True, related_name='pages') class Meta: unique_together = ( ('book', 'ordinal'), ) ordering = ( 'book', 'ordinal', ) def __str__(self): return f"{self.book} [#{self.ordinal}]" def get_absolute_url(self, d=0): return reverse('books:page', args=(self.book_id, self.ordinal + d)) def preview_url(self): return get_img_url(self.img_id) def thumb_url(self): return get_thumb_url(self.img_id, self.THUMB_HEIGHT) def thumb_width(self): return int(self.THUMB_HEIGHT / self.height * self.width) def is_first(self): return self.ordinal == self.book.num_pages def is_last(self): return self.ordinal == self.book.num_pages def prev_page_url(self): return self.get_absolute_url(-1) def next_page_url(self): return self.get_absolute_url(1)
class CategoryCollection(models.Model): category_list = TreeManyToManyField('Category', blank=True, default=None, verbose_name='Список категорий', ) is_active_custom_order_group = models.BooleanField(default=True, verbose_name='Применить индивидуальный порядок групп атрибутов') is_active_custom_order_shot_parameters = models.BooleanField(default=True, verbose_name='Применить индивидуальный порядок ' 'кратких характеристик') is_active_custom_order_mini_parameters = models.BooleanField(default=True, verbose_name='Применить индивидуальный порядок мини ' 'характеристик') # def __init__(self, *args, **kwargs): # передалаю форму и это будет реализовано там по уловию поле category_list изменено # super().__init__(*args, **kwargs) # # old_group_list = set(ItemOfCustomOrderGroup.objects.filter(category_collection=self).values_list( # 'group_id', flat=True)) # if self.id: # new_group_list = set(map(lambda x: x.id, AttrGroup.objects.filter( # related_categories__category__in=self.category_list.all()))) # else: # new_group_list = set() # if not old_group_list == new_group_list: # del_group_id = old_group_list - new_group_list # ItemOfCustomOrderGroup.objects.filter(group_id__in=del_group_id, category_collection=self).delete() class Meta: verbose_name = "Набор категорий с индивидуальным порядком групп атрибутов" verbose_name_plural = "Наборы категорий с индивидуальным порядком групп атрибутов" def __str__(self): if self.category_list.exists(): return " / ".join(map(str, self.category_list.all().order_by('id').order_by('mptt_level'))) else: return "" def update_group_in_product(self): Product.objects.filter(category_collection_id=self.id).update( custom_order_group=[ [x[0], x[1]] for x in self.rel_group_iocog.order_by('position').values_list('category', 'group') ] )
class Post(models.Model): class Meta: verbose_name = 'Post' verbose_name_plural = 'Posts' title = models.CharField(max_length=128) slug = models.SlugField(max_length=150) sub_title = models.CharField(max_length=512, help_text="A short description of the post") thumbnail = models.ImageField( null=True, blank=True, upload_to='thumbnails/', default='thumbnails/default.png', validators=[validate_thumbnail_size], help_text="Upload a 200x200 image less than 256kb.") content = RichTextUploadingField(config_name='full') categories = TreeManyToManyField(Category, related_name="category_posts") published = models.BooleanField(default=False) created_on = models.DateTimeField(default=timezone.now) updated_on = models.DateTimeField(default=timezone.now) def clean(self): if self.thumbnail: w, h = get_image_dimensions(self.thumbnail) if w != 200: raise ValidationError( f"The thumbnail is {w}px. Please make sure its 200x200.") if h != 200: raise ValidationError( f"The thumbnail is {h}px. Please make sure its 200x200.") super(Post, self).clean() def save(self, *args, **kwargs): self.updated_on = timezone.now() if not self.pk: self.slug = slugify( f"{self.title}-{dateformat.format(timezone.now(), 'Y-m-d-H-i-s')}" ) super(Post, self).save(*args, **kwargs) def __str__(self): return f"{self.title} - Post Id: {self.id}"
class CategoryProductBase(BaseProduct): main_category = TreeForeignKey(get_category_model_string('Category')) additional_categories = TreeManyToManyField( get_category_model_string('Category'), related_name='extra_product_categories') class Meta: abstract = True @models.permalink def get_absolute_url(self): return ('product_detail', (), { 'slug': self.slug, 'path': self.main_category.path }) def save(self, *args, **kwargs): super(CategoryProductBase, self).save(*args, **kwargs) self.additional_categories.add(self.main_category)
class Product(Base): """ Модель товара """ title = models.CharField(max_length=255, verbose_name=_('Title')) slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug')) sections = TreeManyToManyField(Section, verbose_name=_('Sections')) image = ImageField(upload_to='catalog', verbose_name=_('Image'), blank=True) price = models.DecimalField(verbose_name=_('Price'), default=0, max_digits=11, decimal_places=2) sort = models.IntegerField(default=500, verbose_name=_('Sort')) annotation = models.TextField(blank=True, verbose_name=_('Annotation')) text = RichTextField(blank=True, verbose_name=_('Text')) comments = models.BooleanField(default=False, verbose_name=_('Comments')) metatitle = models.CharField(max_length=2000, blank=True, verbose_name=_('Title')) keywords = models.CharField(max_length=2000, blank=True, verbose_name=_('Keywords')) description = models.CharField(max_length=2000, blank=True, verbose_name=_('Description')) def get_absolute_url(self): return reverse('midnight_catalog:catalog_detail', kwargs={'section_slug': self.sections.all()[0].slug, 'slug': self.slug}) def __str__(self): return self.title class Meta: verbose_name = _('Product') verbose_name_plural = _('Products')
class Movie(models.Model): class Meta: ordering = ["title"] verbose_name = _("Movie") verbose_name_plural = _("Movies") title = models.CharField(_("Title"), max_length=255) genres = models.ManyToManyField(Genre, blank=True) directors = models.ManyToManyField(Director, blank=True) actors = models.ManyToManyField(Actor, blank=True) release_year = models.PositiveSmallIntegerField( _("Release year"), validators=[ MinValueValidator(1888), MaxValueValidator(datetime.now().year) ], default=datetime.now().year) rating = models.DecimalField( _("Rating"), decimal_places=1, max_digits=3, validators=[MinValueValidator(0), MaxValueValidator(10)]) rank = models.PositiveIntegerField(unique=True, blank=False, null=False, default=0) featured = models.BooleanField(default=False) commercial = models.BooleanField(default=False) independent = models.BooleanField(default=False) categories = TreeManyToManyField(Category, verbose_name=_("Categories")) @property def rating_percentage(self): """Convert 0-10 rating into a 0-100 percentage""" return int(self.rating * 10) def __str__(self): return self.title
class Priorytet(SprawdzZakresyMixin, models.Model): parent = models.ForeignKey(ZyczeniaPracownika, models.CASCADE) start = models.DateField(db_index=True) koniec = models.DateField(db_index=True) piony = TreeManyToManyField(Pion, related_name="+") priorytet = models.PositiveSmallIntegerField(default=50, validators=[ MaxValueValidator(100), MinValueValidator(1) ]) adnotacja = models.CharField(max_length=100, blank=True, null=True) # TODO: zrobić SQL-constraint testujący na okoliczność zbieżnych czasokresów class Meta: verbose_name = "priorytet" verbose_name_plural = "priorytety" def __str__(self): piony = ", ".join([str(x) for x in self.piony.all()]) b = f"{self.parent.user} dla {piony} ma priorytet {self.priorytet} {self.adnotacja or ''} od {self.start}" if self.koniec is not None: b += f" do {self.koniec}" return b
class ReferencingModel(models.Model): fk = TreeForeignKey(Category, related_name='+', on_delete=models.CASCADE) one = TreeOneToOneField(Category, related_name='+', on_delete=models.CASCADE) m2m = TreeManyToManyField(Category, related_name='+')
class Material(models.Model): name = models.CharField(verbose_name=_("name"), max_length=150, unique=True) description = RichTextField( verbose_name=_("description"), blank=True, config_name="basic_ckeditor", help_text=_( "Additional information about the material. Displayed in the shop." ), ) categories = TreeManyToManyField(Category, related_name="materials") gm = models.BooleanField(verbose_name=_("GM"), help_text=_("Is GM needed for this material?")) lendable = models.BooleanField( verbose_name=_("lendable"), default=False, help_text=_("Should this material be shown for lending?"), ) location = models.ForeignKey( Location, on_delete=models.SET_NULL, blank=True, null=True, verbose_name=_("location"), help_text=_("Where can this material be found?"), related_name="materials", ) rate_class = models.ForeignKey( RateClass, on_delete=models.SET_NULL, blank=True, null=True, verbose_name=_("rate class"), related_name="materials", help_text=_( "What rate class should this material be associated with?"), ) stock_value = models.FloatField( verbose_name=_("stock value"), null=True, blank=True, help_text=_("How many exemplars are there of this material?"), ) stock_unit = models.CharField( verbose_name=_("stock unit"), max_length=150, blank=True, help_text=_("Specify a unit for the stock. E.g. meters."), ) last_modified = models.DateTimeField(auto_now=True, editable=False) class Meta: verbose_name = _("material") verbose_name_plural = _("materials") get_latest_by = "last_modified" ordering = [Lower("name")] def __str__(self): return self.name @property def stock(self): """ Returns a human readable representation of the stock :return: """ parts = [] if self.stock_value: value = "{:.2f}".format(self.stock_value).rstrip("0").rstrip(".") parts.append(value) if self.stock_unit: parts.append(self.stock_unit) return " ".join(parts).strip() stock.fget.short_description = _("stock") @property def sku(self): return self.id + settings.SHOP_SKU_OFFSET @staticmethod def last_modification(): try: return Material.objects.latest().last_modified except Material.DoesNotExist: return None def get_absolute_url(self): return reverse("catalog:material", kwargs={"pk": self.pk}) def get_shop_url(self): if self.lendable and settings.SHOP_PRODUCT_URL_FORMAT: return settings.SHOP_PRODUCT_URL_FORMAT.format(sku=self.sku) else: return None
class Service(models.Model): ## User requesting service: # 'serviceUsername' refactored to 'serviceUserid' which shows better its true nature # decision taken to change Foreign Key from 'Profile' to 'User' until full develop of "user registration" serviceUserId=models.ForeignKey(User ,on_delete=models.CASCADE, null=True) serviceSeqCenter=models.CharField(_("Sequencing center"),max_length=50,blank=False,null=True) serviceRequestNumber=models.CharField(max_length=80, null=True) serviceRequestInt=models.CharField(max_length=80, null=True) ## 'serviceRunID' is not used in forms.py/serviceRequestForm() or rest of code ## Addition of member 'serviceProjectNames' to support # implementation of drop down menu to choose a project name of a list of projects # belonging to the logged-in user in the service request form serviceProjectNames=models.ManyToManyField('iSkyLIMS_wetlab.Projects',verbose_name=_("User's projects"),blank=True) servicePlatform=models.ForeignKey(Platform ,on_delete=models.CASCADE , verbose_name=_("Sequencing platform"),blank=True,null=True) serviceRunSpecs=models.CharField(_("Run specifications"),max_length=10,blank=True,null=True) serviceFileExt=models.ForeignKey(FileExt ,on_delete=models.CASCADE ,verbose_name=_("File extension"),blank=True,null=True) serviceAvailableService=TreeManyToManyField(AvailableService,verbose_name=_("AvailableServices")) serviceFile=models.FileField(_("Service description file"),upload_to=service_files_upload, null=True,blank=True) serviceStatus=models.CharField(_("Service status"),max_length=15,choices=STATUS_CHOICES) serviceNotes=models.TextField(_("Service Notes"),max_length=2048,null=True) serviceCreatedOnDate= models.DateField(auto_now_add=True,null=True) #serviceCreatedOnDate= models.DateField(auto_now_add=False) serviceOnApprovedDate = models.DateField(auto_now_add=False, null=True,blank=True) serviceOnRejectedDate = models.DateField(auto_now_add=False, null=True,blank=True) #serviceOnQueuedDate = models.DateField(auto_now_add=False, null=True) #serviceOnInProgressDate = models.DateField(auto_now_add=False, null=True) serviceOnDeliveredDate = models.DateField(auto_now_add=False, null=True) #serviceOnArchivedDate = models.DateField(auto_now_add=False, null=True) def __str__ (self): return '%s' %(self.serviceRequestNumber) def get_service_information (self): platform = str(self.servicePlatform) return '%s;%s;%s;%s' %(self.serviceRequestNumber ,self.serviceRunSpecs, self.serviceSeqCenter, platform) def get_service_information_with_service_name (self): platform = str(self.servicePlatform) if Resolution.objects.filter(resolutionServiceID__exact = self).exists(): resolutions = Resolution.objects.filter(resolutionServiceID__exact = self).last() folder_name = resolutions.resolutionFullNumber if folder_name is None: resolution_for_service = '' else: folder_name_split= folder_name.split('_') resolution_for_service= '_'.join( folder_name_split[2:-1]) assigned_to = resolutions.resolutionAsignedUser if assigned_to is None: assigned_to = '' else: resolutions_for_service = '' assigned_to = '' if self.serviceOnApprovedDate is None: approved_date = 'Not defined' else: approved_date = self.serviceOnApprovedDate.strftime("%d %B, %Y") if resolutions.resolutionEstimatedDate is None: estimated_date = 'Not defined' else: estimated_date = resolutions.resolutionEstimatedDate.strftime("%d %B, %Y") return '%s;%s;%s;%s;%s;%s;%s;%s' %(self.serviceRequestNumber ,resolution_for_service , assigned_to, approved_date, estimated_date, self.serviceRunSpecs, self.serviceSeqCenter, platform) def get_service_dates (self): service_dates =[] service_dates.append(self.serviceCreatedOnDate.strftime("%d %B, %Y")) if self.serviceOnApprovedDate is None: if self.serviceStatus == 'rejected': service_dates.append('--') else: service_dates.append('Approved Date not set') else: service_dates.append(self.serviceOnApprovedDate.strftime("%d %B, %Y")) if self.serviceOnRejectedDate is None: if self.serviceStatus != 'recorded': service_dates.append('--') else: service_dates.append('Rejected Date not set') else: service_dates.append(self.serviceOnRejectedDate.strftime("%d %B, %Y")) return service_dates def get_stats_information (self): stats_information =[] stats_information.append(self.id) stats_information.append(self.serviceRequestNumber) stats_information.append(self.serviceStatus) stats_information.append(self.serviceCreatedOnDate.strftime("%d %B, %Y")) if self.serviceOnApprovedDate is None: if self.serviceOnRejectedDate is None: stats_information.append('--') else: stats_information.append(self.serviceOnRejectedDate.strftime("%d %B, %Y")) else: stats_information.append(self.serviceOnApprovedDate.strftime("%d %B, %Y")) if self.serviceOnDeliveredDate is None: stats_information.append('--') else: stats_information.append(self.serviceOnDeliveredDate.strftime("%d %B, %Y")) return stats_information def get_service_creation_time (self): return self.serviceCreatedOnDate.strftime("%d %B, %Y") def get_time_to_delivery (self): if self.serviceOnDeliveredDate == self.serviceCreatedOnDate : return 1 else: number_days, time = str(self.serviceOnDeliveredDate - self.serviceCreatedOnDate).split(',') number, string_value = number_days.split(' ') return number
class AccessCard(AdminAbsoluteUrlMixin, TimeStampMixin, Regionalizable, models.Model, metaclass=TransitionWorkflowBaseWithPermissions): visual_number = models.CharField( max_length=255, null=False, blank=False, unique=True, help_text=_('Number visible on the access card')) system_number = models.CharField( max_length=255, null=False, blank=False, unique=True, help_text=_('Internal number in the access system')) issue_date = models.DateField(null=True, blank=True, help_text=_('Date of issue to the User')) notes = models.TextField(null=True, blank=True, help_text=_('Optional notes')) user = models.ForeignKey(RalphUser, null=True, blank=True, related_name='+', help_text=_('User of the card'), on_delete=models.SET_NULL) owner = models.ForeignKey(RalphUser, null=True, blank=True, related_name='+', help_text=('Owner of the card'), on_delete=models.SET_NULL) status = TransitionField(choices=AccessCardStatus(), default=AccessCardStatus.new.id, null=False, blank=False, help_text=_('Access card status')) access_zones = TreeManyToManyField(AccessZone, blank=True, related_name='access_cards') def __str__(self): return _('Access Card: {}').format(self.visual_number) @classmethod def get_autocomplete_queryset(cls): return cls._default_manager.exclude( status=AccessCardStatus.liquidated.id) @classmethod @transition_action() def unassign_user(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_user'] = str( instance.user) instance.user = None @classmethod @transition_action( form_fields={ 'user': { 'field': forms.CharField(label=_('User')), 'autocomplete_field': 'user', 'default_value': partial(autocomplete_user, field_name='user') } }, ) def assign_user(cls, instances, **kwargs): user = get_user_model().objects.get(pk=int(kwargs['user'])) for instance in instances: instance.user = user @classmethod @transition_action( form_fields={ 'owner': { 'field': forms.CharField(label=_('Owner')), 'autocomplete_field': 'owner', 'default_value': partial(autocomplete_user, field_name='owner') } }, help_text=_('assign owner'), ) def assign_owner(cls, instances, **kwargs): owner = get_user_model().objects.get(pk=int(kwargs['owner'])) for instance in instances: instance.owner = owner @classmethod @transition_action() def unassign_owner(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_owner'] = str( instance.owner) instance.owner = None @classmethod @transition_action() def clear_access_zones(cls, instances, requester, **kwargs): for instance in instances: instance.access_zones.clear() @classmethod @transition_action( form_fields={'notes': { 'field': forms.CharField(label=_('notes')), }}) def add_notes(cls, instances, **kwargs): for instance in instances: instance.notes = '{}\n{}'.format(instance.notes, kwargs['notes']) @classmethod @transition_action(run_after=['release_report']) def assign_requester_as_an_owner(cls, instances, requester, **kwargs): """Assign current user as an owner""" for instance in instances: instance.owner = requester instance.save() @classmethod @transition_action( form_fields={ 'accept': { 'field': forms.BooleanField( label=_('I have read and fully understand and ' 'accept the agreement.')) }, }) def accept_asset_release_agreement(cls, instances, requester, **kwargs): pass @classmethod @transition_action(form_fields={ 'report_language': { 'field': forms.ModelChoiceField( label=_('Release report language'), queryset=ReportLanguage.objects.all().order_by('-default'), empty_label=None), 'exclude_from_history': True } }, return_attachment=True, run_after=['assign_owner', 'assign_user']) def release_report(cls, instances, requester, transition_id, **kwargs): report_name = get_report_name_for_transition_id(transition_id) return generate_report(instances=instances, name=report_name, requester=requester, language=kwargs['report_language'], context=cls._get_report_context(instances)) @classmethod @transition_action(run_after=['release_report']) def send_attachments_to_user(cls, requester, transition_id, **kwargs): context_func = get_hook('back_office.transition_action.email_context') send_transition_attachments_to_user(requester=requester, transition_id=transition_id, context_func=context_func, **kwargs) @classmethod def _get_report_context(cls, instances): context = [{ 'visual_number': obj.visual_number, } for obj in instances] return context
class Blog(Post): class Meta: ordering = ('-created', ) short_body = models.TextField(verbose_name='Анонс', blank=True) body = RichTextUploadingField(verbose_name='Содержимое', blank=True) image = ImageField(verbose_name='Изображение', upload_to='blog', blank=True, null=True, max_length=300) category = TreeManyToManyField(Category, verbose_name='Категория', db_index=True) objects = super_models.PostManager() rate_type = 'votes' # can_be_rated = True def type_str(self): return 'Запись блога' @property def thumb110(self): try: return get_thumbnail( self.image, '110x200', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def thumb150(self): try: return get_thumbnail( self.image, '150x300', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def thumb220(self): try: return get_thumbnail( self.image, '220x400', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def thumb360(self): try: return get_thumbnail( self.image, '360x720', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def anons(self): if self.short_body: return self.short_body else: return helper.cut_text(strip_tags(self.body), 200) @cached_property def mark(self): try: mark = History.objects.filter( post=self, history_type=super_models.HISTORY_TYPE_POST_RATED, deleted=False).aggregate(Count('pk'))['pk__count'] if mark is None: mark = 0 except: mark = 0 return mark
class Categorizable: """ A mixin to attach categorization behavior to another model. """ categories = TreeManyToManyField(Category, verbose_name=_("Categories"))
class Atividade(models.Model): pendente = models.BooleanField(default=True) observacoes = models.TextField(blank=True, verbose_name='observações') festival = models.ForeignKey(Festival, on_delete=models.CASCADE) encontro = models.ForeignKey(Encontro, null=True, blank=True, on_delete=models.CASCADE) categorias = TreeManyToManyField(Categoria) tags = models.ManyToManyField(Tag, blank=True) rede = models.ForeignKey(Rede, null=True, blank=True, on_delete=models.CASCADE) espaco = models.ForeignKey(Espaco, null=True, blank=True, on_delete=models.CASCADE, verbose_name='espaço') responsavel = models.ForeignKey(Pessoa, related_name='responsavel_por', on_delete=models.CASCADE, verbose_name='responsável') convidades = models.ManyToManyField(Pessoa, blank=True, related_name='convidade_para') coluna = models.IntegerField(default=1) inicio = models.DateTimeField(verbose_name='início', null=True, blank=True) fim = models.DateTimeField(null=True, blank=True) titulo = models.CharField(max_length=255, verbose_name='título') descricao = models.TextField(verbose_name='descrição', null=True, blank=True) def clean(self): if not self.espaco and not self.pendente: raise ValidationError("O evento deve ter espaço, ou ser marcado como pendente") if not self.pendente and (self.inicio is None or self.fim is None): raise ValidationError("O evento deve ter início e fim, ou ser marcado como pendente") if self.inicio is None or self.fim is None: return if self.inicio >= self.fim: raise ValidationError("Horário de início deve ser anterior ao fim") if self.espaco is None: return return qs = Atividade.objects.filter(espaco=self.espaco, coluna=self.coluna) time_filters = (Q(inicio__lte=self.inicio, fim__gt=self.inicio) | Q(inicio__lt=self.fim, fim__gte=self.fim) | Q(inicio__lte=self.inicio, fim__gte=self.fim) | Q(inicio__gte=self.inicio, fim__lte=self.fim)) qs = qs.filter(time_filters) if self.id: qs = qs.exclude(id=self.id) if qs.count() > 0: raise ValidationError("Este horário conflita com outro evento no mesmo espaço") @property def categoria(self): return self.subcategoria.categoria def __str__(self): return self.titulo
class ZyczeniaPracownika(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) dozwolone_piony = TreeManyToManyField(Pion, related_name="+") dniowka_co_ile_dni = models.PositiveIntegerField( "Jest w stanie wziąć dniówkę co tyle dni od ostatniej", default=1 ) dyzur_co_ile_dni = models.PositiveIntegerField( "Jest w stanie wziąć dyżur co tyle dni od ostatniego ciągu pracy", default=2, ) maks_godzin_ciaglej_pracy = models.PositiveIntegerField( "Maksymalna ilość godzin ciągłej pracy", default=24, ) min_odpoczynek_po_ciaglej_pracy = models.PositiveIntegerField( "Czas bez pracy po godzinach ciągłej pracy", default=11, validators=[ MaxValueValidator(24) ] ) priorytet_bazowy = models.PositiveSmallIntegerField(default=50) maks_dniowki = models.PositiveSmallIntegerField("Maks. dniówek", default=None, blank=True, null=True) maks_dniowki_w_tygodniu = models.PositiveSmallIntegerField("Maks. dniówek w tygodniu", default=None, blank=True, null=True) maks_dyzury = models.PositiveSmallIntegerField("Maks. dyżurów", default=None, blank=True, null=True) maks_dobowe = models.PositiveSmallIntegerField("Maks. dobowych", default=None, blank=True, null=True) maks_zwykle = models.PositiveSmallIntegerField("Maks. zwykłych", default=None, blank=True, null=True) nie_dyzuruje_z = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="+", blank=True) specjalizacja = models.SmallIntegerField( null=True, default=None, choices=( (None, "żaden"), (const.REZYDENT, "rezydent"), (const.JEDYNKOWICZ, "jedynkowicz"), (const.SPECJALISTA, "specjalista") ), ) emeryt = models.BooleanField(default=False) class Meta: verbose_name_plural = 'życzenia pracowników' verbose_name = 'życzenia pracownika' def __str__(self): ret = f"Życzenia dla {self.user}" if self.maks_dobowe is not None: ret += f" - weźmie {self.maks_dobowe} dobowych dyżurów" if self.maks_zwykle is not None: ret += f" - weźmie {self.maks_zwykle} zwykłych dyżurów" return ret def wszystkie_dozwolone_piony(self): s = set() for pion in self.dozwolone_piony.all(): s.add(pion) for pion in pion.get_descendants(): s.add(pion) return s
class AccessCard(AdminAbsoluteUrlMixin, TimeStampMixin, Regionalizable, models.Model, metaclass=TransitionWorkflowBaseWithPermissions): visual_number = models.CharField( max_length=255, null=False, blank=False, unique=True, help_text=_('Number visible on the access card')) system_number = models.CharField( max_length=255, null=False, blank=False, unique=True, help_text=_('Internal number in the access system')) issue_date = models.DateField(null=True, blank=True, help_text=_('Date of issue to the User')) notes = models.TextField(null=True, blank=True, help_text=_('Optional notes')) user = models.ForeignKey(RalphUser, null=True, blank=True, related_name='+', help_text=_('User of the card'), on_delete=models.SET_NULL) owner = models.ForeignKey(RalphUser, null=True, blank=True, related_name='+', help_text=('Owner of the card'), on_delete=models.SET_NULL) status = TransitionField(choices=AccessCardStatus(), default=AccessCardStatus.new.id, null=False, blank=False, help_text=_('Access card status')) access_zones = TreeManyToManyField(AccessZone, blank=True, related_name='access_cards') def __str__(self): return _('Access Card: {}').format(self.visual_number) @classmethod def get_autocomplete_queryset(cls): return cls._default_manager.exclude( status=AccessCardStatus.liquidated.id) @classmethod @transition_action() def unassign_user(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_user'] = str( instance.user) instance.user = None @classmethod @transition_action( form_fields={ 'user': { 'field': forms.CharField(label=_('User')), 'autocomplete_field': 'user', 'default_value': partial(autocomplete_user, field_name='user') } }, ) def assign_user(cls, instances, **kwargs): user = get_user_model().objects.get(pk=int(kwargs['user'])) for instance in instances: instance.user = user @classmethod @transition_action( form_fields={ 'owner': { 'field': forms.CharField(label=_('Owner')), 'autocomplete_field': 'owner', 'default_value': partial(autocomplete_user, field_name='owner') } }, help_text=_('assign owner'), ) def assign_owner(cls, instances, **kwargs): owner = get_user_model().objects.get(pk=int(kwargs['owner'])) for instance in instances: instance.owner = owner @classmethod @transition_action() def unassign_owner(cls, instances, **kwargs): for instance in instances: kwargs['history_kwargs'][instance.pk]['affected_owner'] = str( instance.owner) instance.owner = None
class Idea(CreationModificationDateBase, UrlBase): uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) author = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_("Author"), on_delete=models.SET_NULL, blank=True, null=True, related_name="authored_ideas1", ) title = models.CharField(_("Title"), max_length=200) content = models.TextField(_("Content")) picture = models.ImageField( _("Picture"), upload_to=upload_to ) picture_social = ImageSpecField( source="picture", processors=[ResizeToFill(1024, 512)], format="JPEG", options={"quality": 100}, ) picture_large = ImageSpecField( source="picture", processors=[ResizeToFill(800, 400)], format="PNG" ) picture_thumbnail = ImageSpecField( source="picture", processors=[ResizeToFill(728, 250)], format="PNG" ) categories = TreeManyToManyField( "categories1.Category", verbose_name=_("Categories"), related_name="category_ideas", ) rating = models.PositiveIntegerField( _("Rating"), choices=RATING_CHOICES, blank=True, null=True ) class Meta: verbose_name = _("Idea") verbose_name_plural = _("Ideas") def __str__(self): return self.title def get_url_path(self): return reverse("ideas:idea_detail", kwargs={"pk": self.pk}) @property def structured_data(self): from django.utils.translation import get_language lang_code = get_language() data = { "@type": "CreativeWork", "name": self.translated_title, "description": self.translated_content, "inLanguage": lang_code, } if self.author: data["author"] = { "@type": "Person", "name": self.author.get_full_name() or self.author.username, } if self.picture: data["image"] = self.picture_social.url return data def delete(self, *args, **kwargs): from django.core.files.storage import default_storage if self.picture: with contextlib.suppress(FileNotFoundError): default_storage.delete(self.picture_social.path) default_storage.delete(self.picture_large.path) default_storage.delete(self.picture_thumbnail.path) self.picture.delete() super().delete(*args, **kwargs)
class Product(models.Model): RATING = ( (1, " * "), (2, " * * "), (3, " * * * "), (4, " * * * * "), (5, " * * * * * ") ) WARRANTY = ( (1, "12 мес."), (2, "6 мес."), (3, "3 мес."), (4, "14 дней"), ) name = models.CharField(max_length=128, default=None, unique=True, db_index=True, verbose_name='Название') is_active = models.BooleanField(default=True, verbose_name='Активно') slug = models.SlugField(max_length=128, blank=True, null=True, default=None, unique=True) art = models.CharField(max_length=10, blank=True, null=True, default=None, unique=True, verbose_name='Артикул товара') made_in = models.ForeignKey('Country', blank=True, null=True, default=None, on_delete=models.SET_NULL, verbose_name='Страна производства') brand = models.ForeignKey('Brand', blank=True, null=True, default=None, on_delete=models.CASCADE, verbose_name='Торговая марка') description = models.TextField(blank=True, null=True, default=None, verbose_name='Описание товара') rating = models.SmallIntegerField(choices=RATING, default=1, db_index=True) admin_category = TreeForeignKey(Category, blank=True, null=True, default=None, on_delete=models.SET_NULL, verbose_name='Категория товаров админ-панели') categories = TreeManyToManyField(Category, through='ProductInCategory', through_fields=('product', 'category'), related_name='products') category_collection = models.ForeignKey('CategoryCollection', blank=True, null=True, default=None, on_delete=models.SET_NULL, verbose_name='Коллекция категорий') parameters = models.JSONField(default=dict, blank=True, verbose_name='Характеристики товара') parameters_structure = models.JSONField(default=dict, blank=True, verbose_name='') sorted_parameters_structure = models.JSONField(default=list, blank=True, verbose_name='Сортированная структура характеристик') custom_order_group = models.JSONField(default=list, blank=True, verbose_name='Индивидуальный порядок групп атрибутов для сочетания категорий') is_active_custom_order_group = models.BooleanField(default=True, verbose_name='Использоватть порядок групп атрибутов ' 'определенный в коллекции категорий') shot_parameters_structure = models.JSONField(default=dict, blank=True, verbose_name='Структура кратких характеристик товара') mini_parameters_structure = models.JSONField(default=dict, blank=True, verbose_name='Структура мини характеристик товара') shot_parameters_custom_structure = models.JSONField(default=dict, blank=True, verbose_name='Структура кратких характеристик товара для ' 'сочетания категорий') mini_parameters_custom_structure = models.JSONField(default=dict, blank=True, verbose_name='Структура мини характеристик товара для ' 'сочетания категорий') length = models.FloatField(blank=True, null=True, verbose_name='Длина, см') width = models.FloatField(blank=True, null=True, verbose_name='Ширина, см') height = models.FloatField(blank=True, null=True, verbose_name='Высота, см') length_box = models.FloatField(blank=True, null=True, verbose_name='Длина упаковки, см') width_box = models.FloatField(blank=True, null=True, verbose_name='Ширина упаковки, см') height_box = models.FloatField(blank=True, null=True, verbose_name='Высота упаковки, см') weight = models.FloatField(blank=True, null=True, verbose_name='Вес, кг') warranty = models.SmallIntegerField(choices=WARRANTY, default=1, verbose_name='Срок гарантии') url = models.URLField(max_length=128, blank=True, null=True, default=None, unique=True, verbose_name='Ссылка на товар на сайте производителя)') class Meta: ordering = ['name'] verbose_name = "Товар" verbose_name_plural = "Список товаров" def __str__(self): return self.name def get_category_collection_link(self): if self.category_collection_id: return mark_safe("<a href=%s>%s</a>" % ( reverse('admin:products_categorycollection_change', args=(self.category_collection_id,)), self.category_collection)) else: return "Не назначена" get_category_collection_link.short_description = 'Коллекия категорий' get_category_collection_link = property(get_category_collection_link) def get_product_category_link(self): categories_link_list = [ f"<a href={reverse('admin:products_category_change', args=(cat[0],))}>{cat[1]}</a>" for cat in Category.objects.filter(related_products__product=self).values_list('id', 'name') ] return mark_safe(', '.join(categories_link_list)) get_product_category_link.short_description = 'Дополнительные категории' get_product_category_link = property(get_product_category_link) @property def get_link_refresh(self): return "<a href=%s>%s</a>" % (reverse('admin:products_product_change', args=(self.id,)), 'Обновить') @staticmethod def get_sorted_addict_attr(addict_attr_field): addict_attr_sorted_list = [] attribute_data = namedtuple('attribute_data', 'name full_id id value_str value') if not addict_attr_field == {}: for attr_category in sorted(addict_attr_field.values(), key=lambda cat: cat["cat_position"]): addict_attr_sorted_list.extend([ attribute_data( attr_d[1]['name'], attr_d[0], attr_d[1]['id'], attr_d[1]['value_str'], attr_d[1]['value'] ) for attr_d in sorted(attr_category["attributes"].items(), key=lambda attr: attr[1]["pos_atr"]) ]) return addict_attr_sorted_list else: return [] @property def sorted_shot_attributes(self): return self.get_sorted_addict_attr(self.shot_parameters_structure) @property def sorted_mini_attributes(self): return self.get_sorted_addict_attr(self.mini_parameters_structure)
class Drug(Post): body = RichTextField(verbose_name='Описание', blank=True) features = RichTextField(verbose_name='Особенности', blank=True) indications = RichTextField(verbose_name='Показания', blank=True) application_scheme = RichTextField(verbose_name='Схема приема', blank=True) dosage_form = RichTextField(verbose_name='Формы выпуска', blank=True) contra_indications = RichTextField(verbose_name='Противопоказания', blank=True) side_effects = RichTextField(verbose_name='Побочные эффекты', blank=True) compound = RichTextField(verbose_name='Состав', blank=True) image = ImageField(verbose_name='Изображение', upload_to='drug', blank=True, null=True, max_length=300) dosage_forms = models.ManyToManyField(DrugDosageForm, verbose_name='Формы выпуска') usage_areas = models.ManyToManyField(DrugUsageArea, verbose_name='Область применения') components = models.ManyToManyField(Component, verbose_name='Состав', blank=True, related_name='drugs') category = TreeManyToManyField(Category, verbose_name='Категория', blank=True, db_index=True) objects = super_models.PostManager() def type_str(self): return 'Препарат' @property def thumb110(self): try: return get_thumbnail( self.image, '110x200', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def thumb150(self): try: return get_thumbnail( self.image, '150x300', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return '' @property def thumb220(self): try: return get_thumbnail( self.image, '220x400', quality=settings.DEFAULT_THUMBNAIL_QUALITY).url except: return ''
class Service(models.Model): ## User requesting service: # 'serviceUsername' refactored to 'serviceUserid' which shows better its true nature # decision taken to change Foreign Key from 'Profile' to 'User' until full develop of "user registration" serviceUserId = models.ForeignKey(User, on_delete=models.CASCADE, null=True) #servicePlatform = models.ForeignKey( # Platform , # on_delete=models.CASCADE , # verbose_name=_("Sequencing platform"),blank=True,null=True) serviceFileExt = models.ForeignKey(FileExt, on_delete=models.CASCADE, verbose_name=_("File extension"), blank=True, null=True) serviceSequencingPlatform = models.ForeignKey(SequencingPlatform, on_delete=models.CASCADE, null=True, blank=True) serviceAvailableService = TreeManyToManyField( AvailableService, verbose_name=_("AvailableServices")) serviceProjectNames = models.ManyToManyField( 'iSkyLIMS_wetlab.Projects', verbose_name=_("User's projects"), blank=True) serviceSeqCenter = models.CharField(_("Sequencing center"), max_length=50, blank=False, null=True) serviceRequestNumber = models.CharField(max_length=80, null=True) serviceRequestInt = models.CharField(max_length=80, null=True) serviceRunSpecs = models.CharField(_("Run specifications"), max_length=10, blank=True, null=True) #serviceFile=models.FileField(_("Service description file"),upload_to=service_files_upload, null=True,blank=True) serviceStatus = models.CharField(_("Service status"), max_length=15, choices=STATUS_CHOICES) serviceNotes = models.TextField(_("Service Notes"), max_length=2048, null=True, blank=True) serviceCreatedOnDate = models.DateField(auto_now_add=True, null=True) serviceOnApprovedDate = models.DateField(auto_now_add=False, null=True, blank=True) serviceOnRejectedDate = models.DateField(auto_now_add=False, null=True, blank=True) serviceOnDeliveredDate = models.DateField(auto_now_add=False, null=True, blank=True) def __str__(self): return '%s' % (self.serviceRequestNumber) def get_service_information(self): ''' if self.serviceSequencingPlatform == None : platform = "Not Provided" else: platform = self.serviceSequencingPlatform.get_platform_name() ''' return [self.serviceRequestNumber, self.serviceSeqCenter] def get_service_id(self): return '%s' % self.pk def get_service_dates(self): service_dates = [] service_dates.append(self.serviceCreatedOnDate.strftime("%d %B, %Y")) if self.serviceOnApprovedDate is None: if self.serviceStatus == 'rejected': service_dates.append('--') else: service_dates.append('Approved Date not set') else: service_dates.append( self.serviceOnApprovedDate.strftime("%d %B, %Y")) if self.serviceOnRejectedDate is None: if self.serviceStatus != 'recorded': service_dates.append('--') else: service_dates.append('Rejected Date not set') else: service_dates.append( self.serviceOnRejectedDate.strftime("%d %B, %Y")) if self.serviceOnDeliveredDate is None: service_dates.append('--') else: service_dates.append( self.serviceOnDeliveredDate.strftime("%d %B, %Y")) return service_dates def get_stats_information(self): stats_information = [] stats_information.append(self.id) stats_information.append(self.serviceRequestNumber) stats_information.append(self.serviceStatus) stats_information.append( self.serviceCreatedOnDate.strftime("%d %B, %Y")) if self.serviceOnApprovedDate is None: if self.serviceOnRejectedDate is None: stats_information.append('--') else: stats_information.append( self.serviceOnRejectedDate.strftime("%d %B, %Y")) else: stats_information.append( self.serviceOnApprovedDate.strftime("%d %B, %Y")) if self.serviceOnDeliveredDate is None: stats_information.append('--') else: stats_information.append( self.serviceOnDeliveredDate.strftime("%d %B, %Y")) return stats_information def get_service_creation_time(self): return self.serviceCreatedOnDate.strftime("%d %B, %Y") def get_service_creation_time_no_format(self): return self.serviceCreatedOnDate def get_service_delivery_time_no_format(self): return self.serviceOnDeliveredDate def get_delivery_date(self): if self.serviceOnDeliveredDate: return self.serviceOnDeliveredDate.strftime("%d %B, %Y") else: return 'Not yet defined' def get_service_request_integer(self): return '%s' % (self.serviceRequestInt) def get_service_request_number(self): return '%s' % (self.serviceRequestNumber) def get_service_requested_user(self): if self.serviceUserId != None: return '%s' % (self.serviceUserId.username) return 'Not available' def get_user_service_obj(self): return self.serviceUserId def get_service_request_center_unit_abbr(self): return '%s' % (self.serviceUserId.profile.profileCenter.centerAbbr) def get_service_state(self): return '%s' % (self.serviceStatus) def get_service_request_center(self): try: center = serviceUserId.serviceSeqCenter except: center = 'NA' return center def get_service_user_notes(self): return '%s' % (self.serviceNotes) def get_time_to_delivery(self): if self.serviceOnDeliveredDate == self.serviceCreatedOnDate: return 1 else: number_days, time = str(self.serviceOnDeliveredDate - self.serviceCreatedOnDate).split(',') number, string_value = number_days.split(' ') return number def get_username(self): return '%s' % (self.serviceUserId.username) def get_user_email(self): return '%s' % (self.serviceUserId.email) def get_child_services(self): children_services = [] all_services = self.serviceAvailableService.all() for service in all_services: if not service.get_children().exists(): children_services.append( [service.pk, service.get_service_description()]) return children_services def update_approved_date(self, date): self.serviceOnApprovedDate = date self.save() return self def update_service_status(self, status): self.serviceStatus = status self.save() return self def update_service_approved_date(self, date): self.serviceOnApprovedDate = date self.save() return self def update_service_delivered_date(self, date): self.serviceOnDeliveredDate = date self.save() return self def update_service_rejected_date(self, date): self.serviceOnRejectedDate = date self.save() return self def update_sequencing_platform(self, data): self.serviceSequencingPlatform = data self.save() return self objects = ServiceManager()