o2o-negosium-original/negodata/backend/services/company_settings_service.py

77 lines
3.2 KiB
Python

import uuid
from datetime import timedelta
from fastapi import Depends
from common.database.db_session_manager import DB_SESSION_MNG
from common.database.model.models import companies
from common.enums import DBWRType, ErrorType
from common.utils.gtime import GTime
from config.server_configs import web_server_config
from crud.user_crud import IUserCRUD, UserCRUD
from router.v1.company.protocol import (
Req_PreviewInviteEmail,
Req_UpdateCompanySettings,
Res_CompanySettings,
Res_PreviewInviteEmail,
)
from services.email import build_invite_email
class CompanySettingsService:
"""회사별 커스터마이징 설정(companies.settings JSONB) 조회/수정.
- 조회는 로그인 유저 전원(브랜딩/라벨을 앱 부팅 시 로드), 수정은 라우터에서 RequireOwner 로 게이트.
- company_id 는 토큰값만 쓴다 → 남의 회사 설정 접근 불가.
"""
def __init__(self, user_crud: IUserCRUD = Depends(UserCRUD)):
self.user_crud = user_crud
async def get_settings(self, company_id: str) -> Res_CompanySettings:
res = Res_CompanySettings()
err_type, company = await DB_SESSION_MNG.execute_lambda(
companies.DBType(),
DBWRType.DB_READ.value,
lambda s: self.user_crud.get_company(s, uuid.UUID(company_id)),
)
if err_type != ErrorType.SUCCESS or company is None:
res.result.SetResult(err_type if err_type != ErrorType.SUCCESS else ErrorType.ACCOUNT_NOT_FOUND)
return res
res.settings = company.settings
return res
async def update_settings(self, company_id: str, req: Req_UpdateCompanySettings) -> Res_CompanySettings:
res = Res_CompanySettings()
err_type = await DB_SESSION_MNG.execute_lambda_run(
[companies.DBType()],
[lambda s: self.user_crud.update_company_settings(s, uuid.UUID(company_id), req.settings)],
)
if err_type != ErrorType.SUCCESS:
res.result.SetResult(err_type)
return res
res.settings = req.settings
return res
async def preview_invite_email(self, company_id: str, req: Req_PreviewInviteEmail) -> Res_PreviewInviteEmail:
"""저장 전 branding 편집값을 샘플 견적 데이터로 렌더한다(발송 없음).
실제 발송(services/quotation/invites.py)과 같은 build_invite_email 을 타므로 미리보기=실물.
회사명은 헤더 기본값이라 실발송과 동일하게 채워 보여준다."""
res = Res_PreviewInviteEmail()
_, company = await DB_SESSION_MNG.execute_lambda(
companies.DBType(),
DBWRType.DB_READ.value,
lambda s: self.user_crud.get_company(s, uuid.UUID(company_id)),
)
base = (web_server_config.nego_chat_url or "").rstrip("/")
res.subject, res.html, _ = build_invite_email(
supplier_name="샘플 협력사",
quotation_name="복사용지 A4 80g 외 2건",
qt_number="EST-2026-0801",
end_time=GTime.UTC() + timedelta(days=3),
chat_url=f"{base}/chat?session_id=00000000-0000-0000-0000-000000000000",
company_name=(company.name if company else "") or "",
branding=req.branding,
)
return res