from django.utils import timezone from apps.projects.models import ProjectUserRate from apps.workspaces.models import HourlyRateHistory def record_project_rate_history(*, project, user, hourly_rate, currency, effective_from=None): currency = currency.upper() effective_from = effective_from or timezone.now() latest = ( HourlyRateHistory.objects.filter( workspace=project.workspace, project=project, user=user, scope=HourlyRateHistory.Scope.PROJECT, is_deleted=False, ) .order_by("-effective_from", "-created_at") .first() ) if latest and latest.hourly_rate == hourly_rate and latest.currency == currency: return latest return HourlyRateHistory.objects.create( workspace=project.workspace, project=project, user=user, scope=HourlyRateHistory.Scope.PROJECT, hourly_rate=hourly_rate, currency=currency, effective_from=effective_from, is_active=True, ) def get_current_project_user_rate(*, project, user): return ( ProjectUserRate.objects.filter( project=project, user=user, is_active=True, is_deleted=False, ) .order_by("-effective_from", "-updated_at") .first() ) def upsert_project_user_rate(*, project, user, hourly_rate, currency="USD"): currency = currency.upper() rate = ( ProjectUserRate.all_objects.filter( project=project, user=user, ) .order_by("-updated_at", "-created_at") .first() ) effective_from = timezone.now() if rate: update_fields = [] if rate.is_deleted: rate.restore() if rate.hourly_rate != hourly_rate: rate.hourly_rate = hourly_rate update_fields.append("hourly_rate") if rate.currency != currency: rate.currency = currency update_fields.append("currency") if not rate.is_active: rate.is_active = True update_fields.append("is_active") if update_fields: update_fields.append("updated_at") rate.save(update_fields=update_fields) record_project_rate_history( project=project, user=user, hourly_rate=rate.hourly_rate, currency=rate.currency, effective_from=effective_from, ) return rate rate = ProjectUserRate.objects.create( project=project, user=user, hourly_rate=hourly_rate, currency=currency, effective_from=effective_from, is_active=True, ) record_project_rate_history( project=project, user=user, hourly_rate=rate.hourly_rate, currency=rate.currency, effective_from=rate.effective_from, ) return rate def remove_project_user_rate(*, project, user): rate = get_current_project_user_rate(project=project, user=user) if not rate: return False rate.delete() return True