from datetime import timedelta from django import forms from django.utils import timezone from commerce.models import IntegrationConnection, IntegrationStatus from commerce.services.credentials import encrypt_credentials class IntegrationConnectionAdminForm(forms.ModelForm): token = forms.CharField( label="Новый API-токен", required=False, widget=forms.PasswordInput(render_value=False), help_text="Оставьте пустым, чтобы сохранить текущие реквизиты.", ) login = forms.CharField(label="Новый API-логин", required=False) password = forms.CharField( label="Новый пароль", required=False, strip=False, widget=forms.PasswordInput(render_value=False), help_text="Для смены реквизитов укажите и логин, и пароль.", ) class Meta: model = IntegrationConnection fields = [ "provider", "auth_type", "token", "login", "password", "auto_sync", "sync_interval_minutes", ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not self.instance._state.adding and "provider" in self.fields: self.fields["provider"].disabled = True def clean(self): data = super().clean() if self.instance.status in {IntegrationStatus.QUEUED, IntegrationStatus.SYNCING}: raise forms.ValidationError("Дождитесь завершения текущей синхронизации.") auth_type = data.get("auth_type") if data.get("provider") == "wildberries" and auth_type != "token": self.add_error("auth_type", "Wildberries поддерживает только API-токен.") credentials_required = ( not self.instance.encrypted_credentials or auth_type != self.instance.auth_type or any(data.get(key) for key in ("token", "login", "password")) ) self.new_credentials = None if credentials_required: keys = ("token",) if auth_type == "token" else ("login", "password") for key in keys: if not data.get(key): self.add_error(key, "Укажите реквизиты выбранного способа авторизации.") if all(data.get(key) for key in keys): self.new_credentials = {key: data[key] for key in keys} return data def save(self, commit=True): connection = super().save(commit=False) if self.new_credentials: connection.encrypted_credentials = encrypt_credentials(self.new_credentials) connection.status = IntegrationStatus.DISCONNECTED connection.last_error = "" connection.last_tested_at = None if {"auto_sync", "sync_interval_minutes"}.intersection(self.changed_data): connection.next_sync_at = ( timezone.now() + timedelta(minutes=connection.sync_interval_minutes) if connection.auto_sync else None ) if commit: connection.save() self.save_m2m() return connection