def test_update_office_add_naf(self): romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] romes_for_office += [ rome.code for rome in mapping_util.romes_for_naf("4772A") ] office_to_update = OfficeAdminUpdate( sirets=self.office1.siret, name=self.office1.company_name, nafs_to_add="4772A", ) office_to_update.save() # Use a mock to temporarily adjust scoring_util.SCORE_FOR_ROME_MINIMUM # and avoid removing romes if their score is too low. with mock.patch.object(script.scoring_util, 'SCORE_FOR_ROME_MINIMUM', 0): script.update_offices() res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=self.office1.siret) self.assertEqual(len(set(romes_for_office)), len(res['_source']['scores_by_rome']))
def test_nafs_to_add_multi_siret(self): romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] romes_for_office += [ rome.code for rome in mapping_util.romes_for_naf("4772A") ] sirets = [self.office1.siret, self.office2.siret] office_to_update = OfficeAdminUpdate( sirets='\n'.join(sirets), name="Supermarchés", nafs_to_add="4772A", ) office_to_update.save() # Use a mock to temporarily adjust scoring_util.SCORE_FOR_ROME_MINIMUM # and avoid removing romes if their score is too low. with mock.patch.object(script.scoring_util, 'SCORE_FOR_ROME_MINIMUM', 0),\ mock.patch.object(script.scoring_util, 'MINIMUM_POSSIBLE_SCORE', 0): script.update_offices(OfficeAdminUpdate) for siret in sirets: res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=siret) self.assertEqual(len(set(romes_for_office)), len(res['_source']['scores_by_rome']))
def test_update_office_boost_specific_romes(self): """ Test `update_offices` to update an office: boost score for specific ROME codes. """ romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] # Ensure the following ROME codes are related to the office. self.assertIn("D1507", romes_for_office) self.assertIn("D1103", romes_for_office) office_to_update = OfficeAdminUpdate( sirets=self.office1.siret, name=self.office1.company_name, boost=True, romes_to_boost="D1507\nD1103", # Boost score only for those ROME. ) office_to_update.save() script.update_offices(OfficeAdminUpdate) office = Office.get(self.office1.siret) res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=office.siret) # Check boosted scores. self.assertEqual({ 'D1507': True, 'D1103': True, }, res['_source']['boosted_romes'])
def test_no_update_no_company_removal(self): """ No updates done, scores_by_romes and scores_alternance_by_rome should not be impacted Related to a previous bug where some scores where removed. """ # No romes removed when computing scores with mock.patch.object(script.scoring_util, 'SCORE_FOR_ROME_MINIMUM', 0), mock.patch.object( script.scoring_util, 'SCORE_ALTERNANCE_FOR_ROME_MINIMUM', 0): script.update_offices(OfficeAdminUpdate) for office in [self.office1, self.office2]: romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(office.naf) ] res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=office.siret) self.assertIn('scores_by_rome', res['_source']) self.assertIn('scores_alternance_by_rome', res['_source']) self.assertTrue(len(romes_for_office), len(res['_source']['scores_by_rome'])) self.assertTrue(len(romes_for_office), len(res['_source']['scores_alternance_by_rome']))
def fill_values(self, form): try: office = Office.query.filter( Office.siret == form.siret.data).first() except NoResultFound: raise NoOfficeFoundException( 'No office found with siret : {}'.format(form.data.siret)) office_romes = set( [item.code for item in mapping_util.romes_for_naf(office.naf)]) _, lbb_romes, lba_romes, hide_romes = forms.compute_romes() lbb_romes = set(lbb_romes) lba_romes = set(lba_romes) hide_romes = set(hide_romes) # Remove checkboxes and romes not open to applications romes_to_remove = hide_romes.union(office_romes) - lbb_romes # Remove checkboxes and romes not open to alternance romes_alternance_to_remove = hide_romes.union(office_romes) - lba_romes self.romes_to_add = ','.join(lbb_romes - office_romes) self.romes_to_remove = ','.join(romes_to_remove) self.romes_alternance_to_add = ','.join(lba_romes - office_romes) self.romes_alternance_to_remove = ','.join(romes_alternance_to_remove)
def test_update_office_boost_unrelated_romes(self): """ Test `update_offices` to update an office: boost score for specific ROME codes but with romes not associated to the office. """ romes_for_office = [rome.code for rome in mapping_util.romes_for_naf(self.office1.naf)] self.assertNotIn("D1506", romes_for_office) # Rome not related to the office self.assertIn("D1507", romes_for_office) # Rome related to the office office_to_update = OfficeAdminUpdate( sirets=self.office1.siret, name=self.office1.company_name, boost=True, romes_to_boost="D1506\nD1507", # Boost score only for those ROME. ) office_to_update.save() script.update_offices() office = Office.get(self.office1.siret) res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=office.siret) # Check boosted scores. self.assertTrue(res['_source']['boosted_romes']['D1506']) self.assertTrue(res['_source']['boosted_romes']['D1507']) # Other scores should not be boosted. for rome in romes_for_office: if rome != "D1507": self.assertNotIn(rome, res['_source']['boosted_romes'])
def test_romes_to_boost_multi_siret(self): sirets = [self.office1.siret, self.office2.siret] romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] # Ensure the following ROME codes are related to the office. self.assertIn("D1507", romes_for_office) self.assertIn("D1103", romes_for_office) office_to_update = OfficeAdminUpdate( sirets='\n'.join(sirets), name="Supermarchés", boost=True, romes_to_boost="D1507\nD1103", # Boost score only for those ROME. ) office_to_update.save() script.update_offices(OfficeAdminUpdate) for siret in sirets: res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=siret) # Check boosted scores. self.assertTrue(res['_source']['boosted_romes']['D1507']) self.assertTrue(res['_source']['boosted_romes']['D1103'])
def extract_manually_added_jobs(office): """ Return manually added_job as a string : rome1,lbb,lba||rome2,lbb||.... """ values = dict(request.form) office_romes = [ item.code for item in mapping_util.romes_for_naf(office.naf) ] added_romes_codes = [ key for key in values if key not in office_romes and key in ROME_CODES ] added_romes = [] for rome_code in added_romes_codes: added_romes.append({ 'id': rome_code, 'label': settings.ROME_DESCRIPTIONS[rome_code], 'lbb': True if 'lbb' in values.get(rome_code, []) else False, 'lba': True if 'lba' in values.get(rome_code, []) else False, }) return added_romes
def romes_for_siret(): """ Find ROME codes associated with a given SIRET. """ siret = request.args.get('siret') naf = None naf_name = None romes = [] form = SiretForm(siret=siret) if siret and form.validate(): naf = form.office.naf naf_name = settings.NAF_CODES.get(naf) siret = form.siret.data romes = mapping_util.romes_for_naf(naf) context = { 'current_tab': 'romes_for_siret', 'form': form, 'naf': naf, 'naf_name': naf_name, 'romes': romes, 'siret': siret, 'total_hirings_for_naf': sum(rome.nafs[naf] for rome in romes), } return render_template('data/romes_for_siret.html', **context)
def test_romes_to_remove_multi_siret(self): romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] sirets = [self.office1.siret, self.office2.siret] self.assertIn("D1101", romes_for_office) # Rome related to the office self.assertIn("D1507", romes_for_office) # Rome related to the office office_to_update = OfficeAdminUpdate( sirets='\n'.join(sirets), name="Supermarchés", boost=False, romes_to_boost='', romes_to_remove="D1507", # Remove score only for those ROME. ) office_to_update.save() script.update_offices(OfficeAdminUpdate) for siret in sirets: res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=siret) # Check romes self.assertIn('D1101', res['_source']['scores_by_rome']) self.assertNotIn('D1507', res['_source']['scores_by_rome'])
def test_update_office_removed_romes(self): """ Test `update_offices` to update an office: remove specific ROME to an office """ romes_for_office = [ rome.code for rome in mapping_util.romes_for_naf(self.office1.naf) ] self.assertIn("D1101", romes_for_office) # Rome related to the office self.assertIn("D1507", romes_for_office) # Rome related to the office office_to_update = OfficeAdminUpdate( sirets=self.office1.siret, name=self.office1.company_name, boost=False, romes_to_boost='', romes_to_remove="D1507", # Remove score only for those ROME. ) office_to_update.save() script.update_offices(OfficeAdminUpdate) office = Office.get(self.office1.siret) res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=office.siret) # Check rome scores. self.assertIn('D1101', res['_source']['scores_by_rome']) self.assertNotIn('D1507', res['_source']['scores_by_rome']) # Other scores should not be boosted. for rome in romes_for_office: if rome != "D1507": self.assertNotIn(rome, res['_source']['boosted_romes'])
def update_jobs_form(form): try: office = get_office_from_siret(request.args['siret']) except NoResultFound: flash(unknown_siret_message(), 'error') return redirect(url_for('contact_form.change_info')) office_romes = mapping_util.romes_for_naf(office.naf) rome_fields = [] for rome in office_romes: # Retrieve old values current_values = dict(request.form).get(rome.code, ['lbb', 'lba']) rome_fields.append({ 'code': rome.code, 'name': rome.name, 'current_values': current_values }) if form.validate_on_submit(): recruiter_message = models.UpdateJobsRecruiterMessage.create_from_form( form, is_certified_recruiter=peam_recruiter.is_certified_recruiter(), uid=peam_recruiter.get_recruiter_uid()) mail_content = mail.generate_update_jobs_mail(form, recruiter_message) try: mail.send_mail(mail_content, get_subject()) except MailNoSendException as e: logger.exception(e) flash(generate_fail_flash_content(), 'error') else: redirect_params = get_success_value() return render_template( 'contact_form/success_message.html', title="Merci pour votre message", use_lba_template=is_recruiter_from_lba(), site_name=redirect_params.get('site_name'), email=redirect_params.get('email'), home_url=redirect_params.get('home_url'), rome_fields=rome_fields, suggest_update_coordinates=True, params=extract_recruiter_data(), action_form_url=url_for('contact_form.ask_action', **request.args), custom_ga_pageview='/recruteur/update_jobs/success', ) return render_template( 'contact_form/change_job_infos.html', title='Demande de modification des métiers', form=form, params=extract_recruiter_data(), use_lba_template=is_recruiter_from_lba(), manually_added_jobs=extract_manually_added_jobs(office), rome_fields=rome_fields, custom_ga_pageview='/recruteur/update_jobs/update_jobs', )
def test_update_office_with_blank_new_name_companny_office(self): """ Test `update_offices` to update an office: update names, email and website, keep current phone. """ office = Office.get(self.office1.siret) old_company_name = office.company_name old_office_name = office.office_name office_to_update = OfficeAdminUpdate( sirets=self.office1.siret, name=self.office1.name, new_company_name="", new_office_name="", boost=True, new_email="*****@*****.**", new_phone="", # Leave empty on purpose: it should not be modified. new_website="https://foo.pole-emploi.fr", remove_email=False, remove_phone=False, remove_website=False, ) office_to_update.save() script.update_offices(OfficeAdminUpdate) office = Office.get(self.office1.siret) self.assertEqual(office.company_name, old_office_name) self.assertEqual(office.office_name, old_office_name) self.assertEqual(office.email, office_to_update.new_email) self.assertEqual(office.score, office.score) # This value should not be modified. self.assertEqual( office.tel, self.office1.tel) # This value should not be modified. self.assertEqual(office.website, office_to_update.new_website) res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=office.siret) self.assertEqual(res['_source']['email'], office.email) self.assertEqual(res['_source']['phone'], office.tel) self.assertEqual(res['_source']['website'], office.website) # Global score should always be the same. self.assertEqual(res['_source']['score'], office.score) # Check scores for ROME. # Since `romes_to_boost` is empty, all romes should be boosted. self.assertEqual(office_to_update.romes_to_boost, "") for rome in mapping_util.romes_for_naf(office.naf): self.assertTrue(res['_source']['boosted_romes'][rome.code])
def validate_romes_to_remove(self, form, romes_to_remove_field, office_naf=None): romes_to_remove = form.data.get(romes_to_remove_field) for rome in models.OfficeAdminUpdate.as_list(romes_to_remove): self.validate_rome(rome, romes_to_remove_field) if office_naf: office_romes = [ item.code for item in mapping_util.romes_for_naf(office_naf) ] if rome not in office_romes: msg = "`%s` n'est pas un code ROME lié au NAF de cette entreprise. Champ : '%s'" % ( rome, self.column_labels[romes_to_remove_field]) raise RomeToRemoveException(msg)
def test_boost_multi_siret(self): sirets = [self.office1.siret, self.office2.siret] office_to_update = OfficeAdminUpdate( sirets='\n'.join(sirets), name="Supermarché", boost=True, ) office_to_update.save(commit=True) script.update_offices() for siret in sirets: office = Office.get(siret) res = self.es.get(index=settings.ES_INDEX, doc_type=es.OFFICE_TYPE, id=siret) # Since `romes_to_boost` is empty, all `scores_by_rome` should be boosted. self.assertEqual(office_to_update.romes_to_boost, "") for rome in mapping_util.romes_for_naf(office.naf): self.assertTrue(res['_source']['boosted_romes'][rome.code])
def romes_for_naf(): """ Find ROME codes associated with a given NAF code. """ naf = request.args.get('naf') naf_name = None romes = [] form = NafForm(naf=naf) if naf and form.validate(): naf = form.naf.data naf_name = settings.NAF_CODES.get(naf) romes = mapping_util.romes_for_naf(naf) context = { 'current_tab': 'romes_for_naf', 'form': form, 'naf': naf, 'naf_name': naf_name, 'romes': romes, 'total_hirings_for_naf': sum(rome.nafs[naf] for rome in romes), } return render_template('data/romes_for_naf.html', **context)
def generate_update_jobs_mail(form, recruiter_message): office = Office.query.filter(Office.siret == form.siret.data).first() office_romes = [item.code for item in mapping_util.romes_for_naf(office.naf)] all_romes, lbb_romes, lba_romes, hide_romes = forms.compute_romes() return """ {} <br> Intéressé par des candidatures : <ul>{}</ul><br> Pas intéressé par des candidatures : <ul>{}</ul><br> Romes à ajouter LBB : <ul>{}</ul><br> <hr> Ouvert aux contrats d'alternance : <ul>{}</ul><br> Non ouvert à l'alternance : <ul>{}</ul><br> Romes à ajouter LBA : <ul>{}</ul><br> <hr> Romes à retirer : <ul>{}</ul><br> <hr>{}<hr> Cordialement,<br>  La Bonne Boite & La Bonne alternance """.format( common_mail_template(form), # LBB format_romes(lbb_romes), format_romes(set(all_romes) - set(lba_romes)), format_romes(set(lbb_romes) - set(office_romes)), # LBA format_romes(lba_romes), format_romes(set(all_romes) - set(lbb_romes)), format_romes(set(lba_romes) - set(office_romes)), # Remove format_romes(hide_romes), make_save_suggestion( form, recruiter_message, models.UpdateJobsRecruiterMessage.name ), )
def romes_for_naf_mapping(self): """ Returns a list of named tuples for ROME codes matching the company's NAF code. """ return mapping_util.romes_for_naf(self.naf)
def filter_romes(self, romes_str, naf): office_romes = [item.code for item in mapping_util.romes_for_naf(naf)] romes = romes_str.split(',') romes_to_keep = [rome for rome in romes if rome in office_romes] return ','.join(romes_to_keep)