# lingo - payment and billing system # Copyright (C) 2022 Entr'ouvert # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import copy from django.conf import settings from django.db import models from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from lingo.utils.misc import LingoImportError, clean_import_data, generate_slug class Agenda(models.Model): label = models.CharField(_('Label'), max_length=150) slug = models.SlugField(_('Identifier'), max_length=160, unique=True) category_label = models.CharField(_('Category label'), max_length=150, null=True) category_slug = models.SlugField(_('Category identifier'), max_length=160, null=True) check_type_group = models.ForeignKey( 'CheckTypeGroup', verbose_name=_('Check type group'), blank=True, null=True, on_delete=models.SET_NULL, ) regie = models.ForeignKey( 'invoicing.Regie', verbose_name=_('Regie'), blank=True, null=True, on_delete=models.SET_NULL, ) class Meta: ordering = ['label'] def __str__(self): return self.label def save(self, *args, **kwargs): if not self.slug: self.slug = generate_slug(self) super().save(*args, **kwargs) @property def base_slug(self): return slugify(self.label) def export_json(self): return { 'slug': self.slug, 'check_type_group': self.check_type_group.slug if self.check_type_group else None, } @classmethod def import_json(cls, data): data = copy.deepcopy(data) try: agenda = Agenda.objects.get(slug=data['slug']) except Agenda.DoesNotExist: raise LingoImportError(_('Missing "%s" agenda') % data['slug']) if data.get('check_type_group'): try: data['check_type_group'] = CheckTypeGroup.objects.get(slug=data['check_type_group']) except CheckTypeGroup.DoesNotExist: raise LingoImportError(_('Missing "%s" check type group') % data['check_type_group']) agenda.check_type_group = data.get('check_type_group') agenda.save() return False, agenda def get_chrono_url(self): if not settings.KNOWN_SERVICES.get('chrono'): return chrono = list(settings.KNOWN_SERVICES['chrono'].values())[0] chrono_url = chrono.get('url') or '' return '%smanage/agendas/%s/settings/' % (chrono_url, self.slug) class CheckTypeGroup(models.Model): slug = models.SlugField(_('Identifier'), max_length=160, unique=True) label = models.CharField(_('Label'), max_length=150) class Meta: ordering = ['label'] def __str__(self): return self.label def save(self, *args, **kwargs): if not self.slug: self.slug = generate_slug(self) super().save(*args, **kwargs) @property def base_slug(self): return slugify(self.label) @classmethod def import_json(cls, data): check_types = data.pop('check_types', []) data = clean_import_data(cls, data) group, created = cls.objects.update_or_create(slug=data['slug'], defaults=data) for check_type in check_types: check_type['group'] = group CheckType.import_json(check_type) return created, group def export_json(self): return { 'label': self.label, 'slug': self.slug, 'check_types': [a.export_json() for a in self.check_types.all()], } class CheckTypeManager(models.Manager): def absences(self): return self.filter(kind='absence', disabled=False) def presences(self): return self.filter(kind='presence', disabled=False) class CheckType(models.Model): group = models.ForeignKey(CheckTypeGroup, on_delete=models.CASCADE, related_name='check_types') slug = models.SlugField(_('Identifier'), max_length=160) label = models.CharField(_('Label'), max_length=150) kind = models.CharField( _('Kind'), max_length=8, choices=[('absence', _('Absence')), ('presence', _('Presence'))], default='absence', ) pricing = models.DecimalField( _('Pricing'), max_digits=5, decimal_places=2, help_text=_('Fixed pricing'), blank=True, null=True ) pricing_rate = models.PositiveIntegerField( _('Pricing rate'), help_text=_('Percentage rate'), blank=True, null=True ) disabled = models.BooleanField(_('Disabled'), default=False) objects = CheckTypeManager() class Meta: ordering = ['label'] unique_together = ['group', 'slug'] def __str__(self): return self.label def save(self, *args, **kwargs): if not self.slug: self.slug = generate_slug(self, group=self.group) super().save(*args, **kwargs) @property def base_slug(self): return slugify(self.label) @classmethod def import_json(cls, data): data = clean_import_data(cls, data) cls.objects.update_or_create(slug=data['slug'], group=data['group'], defaults=data) def export_json(self): return { 'label': self.label, 'slug': self.slug, 'kind': self.kind, }