Update app callback server

This commit is contained in:
2026-02-17 17:31:32 -05:00
parent 2b4a485819
commit 34d73a6d2c
3 changed files with 826 additions and 20 deletions
+90
View File
@@ -29,6 +29,23 @@ class QBOCredentials:
token_expiry: Optional[str] = None
@dataclass
class ConnectionProfile:
"""Connection profile for QuickBooks Online."""
name: str
client_id: str = ""
client_secret: str = ""
redirect_uri: str = "http://localhost:9000/oauth/callback"
environment: str = "sandbox" # 'sandbox' or 'production'
access_token: Optional[str] = None
refresh_token: Optional[str] = None
realm_id: Optional[str] = None
company_name: Optional[str] = None
token_expiry: Optional[str] = None
created_at: str = field(default_factory=lambda: datetime.now().isoformat())
updated_at: str = field(default_factory=lambda: datetime.now().isoformat())
@dataclass
class FieldMapping:
"""Single field mapping configuration."""
@@ -247,6 +264,79 @@ class Settings:
self.credentials_file.unlink()
logger.info("Credentials cleared")
# Connection Profile management
def get_profiles(self) -> List[ConnectionProfile]:
"""Get all connection profiles."""
profiles = []
profiles_file = self.config_dir / "profiles.json"
if profiles_file.exists():
try:
with open(profiles_file, 'r') as f:
profiles_data = json.load(f)
for p in profiles_data:
profiles.append(ConnectionProfile(**p))
except Exception as e:
logger.warning(f"Failed to load profiles: {e}")
return sorted(profiles, key=lambda p: p.name)
def get_profile(self, name: str) -> Optional[ConnectionProfile]:
"""Get a specific profile by name."""
profiles = self.get_profiles()
for p in profiles:
if p.name == name:
return p
return None
def save_profile(self, profile: ConnectionProfile):
"""Save a connection profile."""
profile.updated_at = datetime.now().isoformat()
profiles = self.get_profiles()
# Update existing or add new
found = False
for i, p in enumerate(profiles):
if p.name == profile.name:
profiles[i] = profile
found = True
break
if not found:
profiles.append(profile)
# Save to file
profiles_file = self.config_dir / "profiles.json"
try:
with open(profiles_file, 'w') as f:
json.dump([asdict(p) for p in profiles], f, indent=2)
logger.info(f"Profile saved: {profile.name}")
except Exception as e:
logger.error(f"Failed to save profile: {e}")
def delete_profile(self, name: str):
"""Delete a connection profile."""
profiles = self.get_profiles()
profiles = [p for p in profiles if p.name != name]
profiles_file = self.config_dir / "profiles.json"
try:
with open(profiles_file, 'w') as f:
json.dump([asdict(p) for p in profiles], f, indent=2)
logger.info(f"Profile deleted: {name}")
except Exception as e:
logger.error(f"Failed to delete profile: {e}")
def get_active_profile_name(self) -> Optional[str]:
"""Get the name of the currently active profile."""
return self._config.get("active_profile", None)
def set_active_profile(self, name: Optional[str]):
"""Set the active profile name."""
self._config["active_profile"] = name
self.save()
logger.info(f"Active profile set to: {name}")
# Template management
def get_templates(self, data_type: Optional[str] = None) -> List[MappingTemplate]:
"""Get all mapping templates, optionally filtered by data type."""