from django.db.models.signals import m2m_changed, post_delete, post_save from django.dispatch import receiver from apps.clients.models import Client from apps.projects.models import Project, ProjectRate, ProjectUserRate from apps.tags.models import Tag from apps.time_entries.models import TimeEntry from apps.workspaces.models import Workspace, WorkspaceMembership from apps.workspaces.models import PriceUnit, WorkspaceUserRate from core.services.cache import ( CACHE_NAMESPACE_PRICE_UNITS, CACHE_NAMESPACE_REPORTS, CACHE_NAMESPACE_WORKSPACE_MEMBERSHIPS, CACHE_NAMESPACE_WORKSPACE_RATES, bump_namespace_version, ) @receiver(post_save, sender=Workspace) def create_owner_membership(sender, instance, created, **kwargs): if created: WorkspaceMembership.objects.create( workspace=instance, user=instance.owner, role=WorkspaceMembership.Role.OWNER, ) def _bump_workspace_reports(instance): workspace_id = getattr(instance, "workspace_id", None) if not workspace_id and hasattr(instance, "project"): workspace_id = getattr(instance.project, "workspace_id", None) if workspace_id: bump_namespace_version(CACHE_NAMESPACE_REPORTS, str(workspace_id)) def _bump_workspace_memberships(instance): workspace_id = getattr(instance, "workspace_id", None) if workspace_id: bump_namespace_version(CACHE_NAMESPACE_WORKSPACE_MEMBERSHIPS, str(workspace_id)) def _bump_workspace_rates(instance): workspace_id = getattr(instance, "workspace_id", None) if workspace_id: bump_namespace_version(CACHE_NAMESPACE_WORKSPACE_RATES, str(workspace_id)) @receiver(post_save, sender=TimeEntry) @receiver(post_delete, sender=TimeEntry) @receiver(post_save, sender=Project) @receiver(post_delete, sender=Project) @receiver(post_save, sender=Client) @receiver(post_delete, sender=Client) @receiver(post_save, sender=Tag) @receiver(post_delete, sender=Tag) @receiver(post_save, sender=ProjectRate) @receiver(post_delete, sender=ProjectRate) @receiver(post_save, sender=ProjectUserRate) @receiver(post_delete, sender=ProjectUserRate) def invalidate_workspace_report_cache(sender, instance, **kwargs): _bump_workspace_reports(instance) @receiver(m2m_changed, sender=TimeEntry.tags.through) def invalidate_workspace_report_cache_for_tags(sender, instance, action, **kwargs): if action in {"post_add", "post_remove", "post_clear"}: _bump_workspace_reports(instance) @receiver(post_save, sender=WorkspaceMembership) @receiver(post_delete, sender=WorkspaceMembership) def invalidate_workspace_membership_caches(sender, instance, **kwargs): _bump_workspace_memberships(instance) _bump_workspace_reports(instance) @receiver(post_save, sender=WorkspaceUserRate) @receiver(post_delete, sender=WorkspaceUserRate) def invalidate_workspace_rate_caches(sender, instance, **kwargs): _bump_workspace_rates(instance) _bump_workspace_reports(instance) @receiver(post_save, sender=PriceUnit) @receiver(post_delete, sender=PriceUnit) def invalidate_price_unit_cache(sender, instance, **kwargs): bump_namespace_version(CACHE_NAMESPACE_PRICE_UNITS)