示例#1
0
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))
示例#2
0
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)
示例#3
0
class CategoryPost(models.Model):
    categories = TreeManyToManyField('Category',
                                     blank=True,
                                     related_name='posts',
                                     verbose_name=_('categorías'))

    class Meta:
        abstract = True
示例#4
0
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')
示例#5
0
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'))
示例#7
0
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)
示例#9
0
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})
示例#10
0
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')
示例#11
0
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)
示例#12
0
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')
            ]
        )
示例#13
0
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}"
示例#14
0
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)
示例#15
0
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')
示例#16
0
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
示例#17
0
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
示例#18
0
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='+')
示例#19
0
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
示例#20
0
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
示例#21
0
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
示例#22
0
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
示例#23
0
class Categorizable:
    """
    A mixin to attach categorization behavior to another model.
    """

    categories = TreeManyToManyField(Category, verbose_name=_("Categories"))
示例#24
0
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
示例#25
0
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
示例#26
0
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
示例#27
0
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)
示例#28
0
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)
示例#29
0
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 ''
示例#30
0
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()