Ejemplo n.º 1
0
    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']))
Ejemplo n.º 2
0
    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']))
Ejemplo n.º 3
0
    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'])
Ejemplo n.º 4
0
    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']))
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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'])
Ejemplo n.º 7
0
    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'])
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
    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'])
Ejemplo n.º 11
0
    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'])
Ejemplo n.º 12
0
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',
    )
Ejemplo n.º 13
0
    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])
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    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])
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
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
        ),
    )
Ejemplo n.º 18
0
 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)
Ejemplo n.º 19
0
    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)