from template_project.application.common.data_structure import to_data_structure from template_project.application.common.enums import EducationGrade, ExperienceType from template_project.application.common.identity_provider import IdentityProvider from template_project.application.common.interactor import to_interactor from template_project.application.common.unit_of_work import UnitOfWork from template_project.application.resume.data_gateway import ( ResumeDataGateway, ResumeEducationDataGateway, ResumeExperienceDataGateway, ResumeProjectDataGateway, ) from template_project.application.resume.entity import ( Resume, ResumeEducation, ResumeExperience, ResumeId, ResumeProject, ) from template_project.application.resume.errors import ResumeDoesBelongUserError, ResumeNotFoundError @to_data_structure class ExperienceInput: place: str description: str months_duration: int @to_data_structure class EducationInput: place: str grade: EducationGrade specialization: str description: str | None = None @to_data_structure class ProjectInput: name: str description: str @to_data_structure class ExperienceItemResponse: place: str description: str months_duration: int @to_data_structure class EducationItemResponse: place: str grade: EducationGrade specialization: str description: str | None @to_data_structure class ProjectItemResponse: name: str description: str @to_data_structure class EditResumeResponse: id: ResumeId position: str location: str about_me: str key_skills: list[str] experience_type: ExperienceType experience: list[ExperienceItemResponse] education: list[EducationItemResponse] projects: list[ProjectItemResponse] @to_interactor class EditResumeInteractor: unit_of_work: UnitOfWork identity_provider: IdentityProvider resume_data_gateway: ResumeDataGateway resume_experience_data_gateway: ResumeExperienceDataGateway resume_education_data_gateway: ResumeEducationDataGateway resume_project_data_gateway: ResumeProjectDataGateway async def execute( self, resume_id: ResumeId, position: str | None, location: str | None, about_me: str | None, key_skills: list[str] | None, experience_type: ExperienceType | None, experience: list[ExperienceInput] | None = None, education: list[EducationInput] | None = None, projects: list[ProjectInput] | None = None, ) -> EditResumeResponse: user = await self.identity_provider.get_current_user() old_resume = await self.resume_data_gateway.load_by_resume_id(resume_id) if old_resume is None: raise ResumeNotFoundError(resume_id=resume_id) if old_resume.user_id != user.id: raise ResumeDoesBelongUserError new_position = position if position is not None else old_resume.position new_location = location if location is not None else old_resume.location new_about_me = about_me if about_me is not None else old_resume.about_me new_key_skills = key_skills if key_skills is not None else old_resume.key_skills new_experience_type = experience_type if experience_type is not None else old_resume.experience_type new_resume = Resume.factory( user_id=user.id, position=new_position, location=new_location, about_me=new_about_me, key_skills=new_key_skills, experience_type=new_experience_type, down_resume_id=old_resume.id, up_resume_id=None, ) await self.unit_of_work.add(new_resume) if experience is not None: for exp in experience: resume_experience = ResumeExperience.factory( resume_id=new_resume.id, place=exp.place, description=exp.description, months_duration=exp.months_duration, ) await self.unit_of_work.add(resume_experience) if education is not None: for edu in education: resume_education = ResumeEducation.factory( resume_id=new_resume.id, place=edu.place, grade=edu.grade, specialization=edu.specialization, description=edu.description, ) await self.unit_of_work.add(resume_education) if projects is not None: for proj in projects: resume_project = ResumeProject.factory( resume_id=new_resume.id, name=proj.name, description=proj.description, ) await self.unit_of_work.add(resume_project) if old_resume.up_resume_id is None: old_resume.up_resume_id = new_resume.id await self.unit_of_work.commit() new_experiences = await self.resume_experience_data_gateway.load_by_resume_id(new_resume.id) new_educations = await self.resume_education_data_gateway.load_by_resume_id(new_resume.id) new_projects = await self.resume_project_data_gateway.load_by_resume_id(new_resume.id) return EditResumeResponse( id=new_resume.id, position=new_resume.position, location=new_resume.location, about_me=new_resume.about_me, key_skills=new_resume.key_skills, experience_type=new_resume.experience_type, experience=[ ExperienceItemResponse( place=exp.place, description=exp.description, months_duration=exp.months_duration, ) for exp in new_experiences ], education=[ EducationItemResponse( place=edu.place, grade=edu.grade, specialization=edu.specialization, description=edu.description, ) for edu in new_educations ], projects=[ ProjectItemResponse( name=proj.name, description=proj.description, ) for proj in new_projects ], )