def build_new(cls, user: User, title: FeedbackTitle,
               description: FeedbackDescription) -> "Feedback":
     return cls(
         key=FeedbackKey.build_new(),
         feedback_user=FeedbackUser.build_from_user(user),
         title=title,
         description=description,
         status=FeedbackStatus.New,
         created_at=utcnow_with_tz(),
     )
    def get(self, user_id: str, feedback_id: str) -> str:
        user_repository = container.get(UserRepository)
        feedback_fetch_service: FeedbackFetchService = container.get(
            FeedbackFetchService)

        user_key = UserKey.build(user_id)
        feedback_key = FeedbackKey.build(feedback_id)
        current_user = user_repository.fetch_by_key(user_key)
        if not isinstance(current_user, CustomerUser):
            raise Forbidden()

        feedback = feedback_fetch_service.execute(user=current_user,
                                                  feedback_key=feedback_key)

        return flask.render_template(
            "feedback/customer/feedback.html",
            current_user=current_user,
            feedback=feedback.feedback,
            comments=feedback.comments,
        )
    def __init__(self, user_repository: UserRepository) -> None:
        self._user_repository = user_repository

        sample_feedbacks = [
            Feedback(
                key=FeedbackKey.build("f20001"),
                feedback_user=FeedbackUser.build_from_user(
                    user=self._user_repository.fetch_by_key(key=UserKey.build("c10001"))
                ),
                title=FeedbackTitle("要望サンプル"),
                description=FeedbackDescription("要望本文"),
                status=FeedbackStatus.New,
                created_at=datetime(2020, 10, 1, 10, 0, 0).astimezone(tz=timezone.utc),
            )
        ]

        self._feedbacks: Dict[FeedbackKey, Feedback] = {
            feedback.key: feedback for feedback in sample_feedbacks
        }

        self._comments: Dict[FeedbackKey, List[FeedbackComment]] = defaultdict(list)
    def post(self, user_id: str, feedback_id: str) -> flask.Response:
        user_repository = container.get(UserRepository)
        feedback_comment_create_service: FeedbackCommentCreateService = container.get(
            FeedbackCommentCreateService)

        user_key = UserKey.build(user_id)
        feedback_key = FeedbackKey.build(feedback_id)
        current_user = user_repository.fetch_by_key(user_key)
        if not isinstance(current_user, CustomerUser):
            raise Forbidden()

        feedback_comment_create_service.execute(
            user=current_user,
            feedback_key=feedback_key,
            feedback_comment_body=FeedbackCommentBody(
                f"コメントです - {utcnow_with_tz().isoformat()}"),
        )

        return flask.redirect(
            location=f"/customer/users/{user_id}/feedbacks/{feedback_id}",
            Response=flask.Response,
        )
    def post(self, user_id: str, feedback_id: str) -> flask.Response:
        user_repository = container.get(UserRepository)
        feedback_status_update_service: FeedbackStatusUpdateService = container.get(
            FeedbackStatusUpdateService)

        user_key = UserKey.build(user_id)
        feedback_key = FeedbackKey.build(feedback_id)
        current_user = user_repository.fetch_by_key(user_key)
        if not isinstance(current_user, SupportUser):
            raise Forbidden()

        form = flask.request.form
        status = FeedbackStatus[form["status"]]

        feedback_status_update_service.execute(user=current_user,
                                               feedback_key=feedback_key,
                                               status=status)

        return flask.redirect(
            location=f"/support/users/{user_id}/feedbacks/{feedback_id}",
            Response=flask.Response,
        )
def build_feedback(
    key: Optional[FeedbackKey] = None,
    feedback_user: Union[None, User, FeedbackUser] = None,
    title: Optional[str] = None,
    description: Optional[str] = None,
    status: Optional[FeedbackStatus] = None,
    now: Optional[datetime.datetime] = None,
) -> Feedback:
    if key is None:
        key = FeedbackKey.build_new()
    if feedback_user is None:
        feedback_user = FeedbackUser.build_from_user(user=build_customer_user())
    if isinstance(feedback_user, User):
        feedback_user = FeedbackUser.build_from_user(user=feedback_user)

    return Feedback(
        key=key,
        feedback_user=feedback_user,
        title=FeedbackTitle(title or "要望のタイトル"),
        description=FeedbackDescription(description or "要望の詳細"),
        status=status or FeedbackStatus.New,
        created_at=now or utcnow_with_tz(),
    )