def test_import_line_items(self):
        '''
        Test that award information is scraped properly.
        '''
        muni = Company.create(**dict(company_name='U.S. Municipal Supply, Inc.'))
        chemung = Company.create(**dict(company_name='Chemung Supply Corporation'))
        pathmaster = Company.create(**dict(company_name='Path Master, Inc., Co.'))

        new_contract = ContractBase.create(
            **dict(properties=[ContractProperty(key='foo', value='6965')], description='foo')
        )

        with open(current_app.config.get('PROJECT_ROOT') + '/purchasing_test/mock/award.html', 'r') as f:
            line_item_page = BeautifulSoup(
                f.read(), from_encoding='windows-1252'
            )

        _line_items = grab_line_items(line_item_page)
        self.assertEquals(len(_line_items), 14)

        contract = get_contract(
            'Sign Post, Square Tubes, Brackets, Etc.',
            'IFB-6965'
        )
        self.assertTrue(contract is not None)
        self.assertEquals(contract.id, new_contract.id)

        save_line_item(_line_items, contract)

        self.assertEquals(LineItem.query.count(), len(_line_items))
        # assert that our ids made it in property
        for item in LineItem.query.all():
            self.assertTrue(item.manufacturer is not None)
            self.assertTrue(item.model_number is not None)
            self.assertEquals(item.contract_id, contract.id)
            if 'muni' in item.company_name.lower():
                self.assertEquals(item.company_id, muni.id)
            elif 'chem' in item.company_name.lower():
                self.assertEquals(item.company_id, chemung.id)
            else:
                self.assertEquals(item.company_id, pathmaster.id)
Example #2
0
    def test_import_line_items(self):
        muni = Company.create(**dict(company_name='U.S. Municipal Supply, Inc.'))
        chemung = Company.create(**dict(company_name='Chemung Supply Corporation'))
        pathmaster = Company.create(**dict(company_name='Path Master, Inc., Co.'))

        new_contract = ContractBase.create(
            **dict(properties=[ContractProperty(key='foo', value='6965')], description='foo')
        )

        with open(current_app.config.get('PROJECT_ROOT') + '/purchasing_test/mock/award.html', 'r') as f:
            line_item_page = BeautifulSoup(
                f.read(), from_encoding='windows-1252'
            )

        _line_items = grab_line_items(line_item_page)
        self.assertEquals(len(_line_items), 14)

        contract = get_contract(
            'Sign Post, Square Tubes, Brackets, Etc.',
            'IFB-6965'
        )
        self.assertTrue(contract is not None)
        self.assertEquals(contract.id, new_contract.id)

        save_line_item(_line_items, contract)

        self.assertEquals(LineItem.query.count(), len(_line_items))
        # assert that our ids made it in property
        for item in LineItem.query.all():
            self.assertTrue(item.manufacturer is not None)
            self.assertTrue(item.model_number is not None)
            self.assertEquals(item.contract_id, contract.id)
            if 'muni' in item.company_name.lower():
                self.assertEquals(item.company_id, muni.id)
            elif 'chem' in item.company_name.lower():
                self.assertEquals(item.company_id, chemung.id)
            else:
                self.assertEquals(item.company_id, pathmaster.id)
def edit_company_contacts(contract_id):
    '''Update information about company contacts, and save all information

    New :py:class:`~purchasing.data.contracts.ContractBase` objects
    are created for each unique controller number. Notifications are
    also sent to all of the original contract's followers to say that
    the contract information has been replaced/updated with new info.

    :param contract_id: Primary key ID for a
        :py:class:`~purchasing.data.contracts.ContractBase`

    .. seealso::

        * :py:class:`~purchasing.conductor.forms.CompanyContactListForm`
        * :py:meth:`~purchasing.data.contracts.ContractBase.create`
        * :py:meth:`~purchasing.data.contracts.ContractBase.complete`
        * :py:class:`~purchasing.notifications.Notification`

    :status 200: Render the CompanyContactListForm form
    :status 302: Post the data and redirect back to the success view, or
        redirect back to contract or company views if those haven't
        been completed yet.
    :status 404: Contract not found
    '''
    contract = ContractBase.query.get(contract_id)

    if contract and session.get(
            'contract-{}'.format(contract_id)) is not None and session.get(
                'companies-{}'.format(contract_id)) is not None:
        form = CompanyContactListForm()

        # pull out companies from session, order them by financial id
        # so that they can be grouped appropriately
        companies = sorted(json.loads(
            session['companies-{}'.format(contract_id)]),
                           key=lambda x: x.get('financial_id'))

        if form.validate_on_submit():
            main_contract = contract
            for ix, _company in enumerate(companies):
                contract_data = json.loads(
                    session['contract-{}'.format(contract_id)])
                # because multiple companies can have the same name, don't use
                # get_or_create because it can create multiples
                if _company.get('company_id') > 0:
                    company = Company.query.get(_company.get('company_id'))
                else:
                    company = Company.create(
                        company_name=_company.get('company_name'))
                # contacts should be unique to companies, though
                try:
                    for _contact in form.data.get('companies')[ix].get(
                            'contacts'):
                        _contact['company_id'] = company.id
                        contact, _ = get_or_create(db.session, CompanyContact,
                                                   **_contact)
                # if there are no contacts, an index error will be thrown for this company
                # so we catch it and just pass
                except IndexError:
                    pass

                contract_data['financial_id'] = _company['financial_id']

                if contract.financial_id is None or contract.financial_id == _company[
                        'financial_id']:
                    contract.update_with_spec_number(contract_data,
                                                     company=company)
                else:
                    contract = ContractBase.clone(contract,
                                                  parent_id=contract.parent_id,
                                                  strip=False)
                    contract.update_with_spec_number(contract_data,
                                                     company=company)

                contract.is_visible = True
                db.session.commit()

            Notification(to_email=[i.email for i in contract.followers],
                         from_email=current_app.config['CONDUCTOR_SENDER'],
                         reply_to=current_user.email,
                         subject='A contract you follow has been updated!',
                         html_template='conductor/emails/new_contract.html',
                         contract=main_contract).send(multi=True)

            session.pop('contract-{}'.format(contract_id))
            session.pop('companies-{}'.format(contract_id))
            session['success-{}'.format(contract_id)] = True

            current_app.logger.info('''
CONDUCTOR CONTRACT COMPLETE - company contacts for contract "{}" assigned. |New contract(s) successfully created'''
                                    .format(contract.description))

            if contract.parent:
                contract.parent.complete()

            return redirect(
                url_for('conductor.success', contract_id=main_contract.id))

        if len(form.companies.entries) == 0:
            for company in companies:
                form.companies.append_entry()

        return render_template('conductor/edit/edit_company_contacts.html',
                               form=form,
                               contract=contract,
                               companies=companies)
    elif session.get('contract-{}'.format(contract_id)) is None:
        return redirect(url_for('conductor.edit', contract_id=contract_id))
    elif session.get('companies-{}'.format(contract_id)) is None:
        return redirect(
            url_for('conductor.edit_company', contract_id=contract_id))
    abort(404)
def edit_company_contacts(contract_id):
    '''Update information about company contacts, and save all information

    New :py:class:`~purchasing.data.contracts.ContractBase` objects
    are created for each unique controller number. Notifications are
    also sent to all of the original contract's followers to say that
    the contract information has been replaced/updated with new info.

    :param contract_id: Primary key ID for a
        :py:class:`~purchasing.data.contracts.ContractBase`

    .. seealso::

        * :py:class:`~purchasing.conductor.forms.CompanyContactListForm`
        * :py:meth:`~purchasing.data.contracts.ContractBase.create`
        * :py:meth:`~purchasing.data.contracts.ContractBase.complete`
        * :py:class:`~purchasing.notifications.Notification`

    :status 200: Render the CompanyContactListForm form
    :status 302: Post the data and redirect back to the success view, or
        redirect back to contract or company views if those haven't
        been completed yet.
    :status 404: Contract not found
    '''
    contract = ContractBase.query.get(contract_id)

    if contract and session.get('contract-{}'.format(contract_id)) is not None and session.get('companies-{}'.format(contract_id)) is not None:
        form = CompanyContactListForm()

        # pull out companies from session, order them by financial id
        # so that they can be grouped appropriately
        companies = sorted(
            json.loads(session['companies-{}'.format(contract_id)]),
            key=lambda x: x.get('financial_id')
        )

        if form.validate_on_submit():
            main_contract = contract
            for ix, _company in enumerate(companies):
                contract_data = json.loads(session['contract-{}'.format(contract_id)])
                # because multiple companies can have the same name, don't use
                # get_or_create because it can create multiples
                if _company.get('company_id') > 0:
                    company = Company.query.get(_company.get('company_id'))
                else:
                    company = Company.create(company_name=_company.get('company_name'))
                # contacts should be unique to companies, though
                try:
                    for _contact in form.data.get('companies')[ix].get('contacts'):
                        _contact['company_id'] = company.id
                        contact, _ = get_or_create(db.session, CompanyContact, **_contact)
                # if there are no contacts, an index error will be thrown for this company
                # so we catch it and just pass
                except IndexError:
                    pass

                contract_data['financial_id'] = _company['financial_id']

                if contract.financial_id is None or contract.financial_id == _company['financial_id']:
                    contract.update_with_spec_number(contract_data, company=company)
                else:
                    contract = ContractBase.clone(contract, parent_id=contract.parent_id, strip=False)
                    contract.update_with_spec_number(contract_data, company=company)

                contract.is_visible = True
                db.session.commit()

            Notification(
                to_email=[i.email for i in contract.followers],
                from_email=current_app.config['CONDUCTOR_SENDER'],
                reply_to=current_user.email,
                subject='A contract you follow has been updated!',
                html_template='conductor/emails/new_contract.html',
                contract=main_contract
            ).send(multi=True)

            session.pop('contract-{}'.format(contract_id))
            session.pop('companies-{}'.format(contract_id))
            session['success-{}'.format(contract_id)] = True

            current_app.logger.info('''
CONDUCTOR CONTRACT COMPLETE - company contacts for contract "{}" assigned. |New contract(s) successfully created'''.format(
                contract.description
            ))

            if contract.parent:
                contract.parent.complete()

            return redirect(url_for('conductor.success', contract_id=main_contract.id))

        if len(form.companies.entries) == 0:
            for company in companies:
                form.companies.append_entry()

        return render_template(
            'conductor/edit/edit_company_contacts.html', form=form, contract=contract,
            companies=companies
        )
    elif session.get('contract-{}'.format(contract_id)) is None:
        return redirect(url_for('conductor.edit', contract_id=contract_id))
    elif session.get('companies-{}'.format(contract_id)) is None:
        return redirect(url_for('conductor.edit_company', contract_id=contract_id))
    abort(404)
Example #5
0
def edit_company_contacts(contract_id):
    contract = ContractBase.query.get(contract_id)

    if contract and session.get('contract') is not None and session.get('companies') is not None:
        form = CompanyContactListForm()

        companies = json.loads(session['companies'])
        contract_data = json.loads(session['contract'])

        if form.validate_on_submit():
            main_contract = contract
            for ix, _company in enumerate(companies):
                # because multiple companies can have the same name, don't use
                # get_or_create because it can create multiples
                if _company.get('company_id') > 0:
                    company = Company.query.get(_company.get('company_id'))
                else:
                    company = Company.create(company_name=_company.get('company_name'))
                # contacts should be unique to companies, though
                for _contact in form.data.get('companies')[ix].get('contacts'):
                    _contact['company_id'] = company.id
                    contact, _ = get_or_create(db.session, CompanyContact, **_contact)

                contract_data['financial_id'] = _company['financial_id']
                if ix == 0:
                    contract.update_with_spec_number(contract_data, company=company)
                else:
                    contract = ContractBase.clone(contract, parent_id=contract.parent_id, strip=False)
                    contract.update_with_spec_number(contract_data, company=company)

                contract.is_visible = True
                contract.parent.is_archived = True
                if not contract.parent.description.endswith('[Archived]'):
                    contract.parent.description += ' [Archived]'

                db.session.commit()

            Notification(
                to_email=[i.email for i in contract.followers],
                from_email=current_app.config['CONDUCTOR_SENDER'],
                reply_to=current_user.email,
                subject='A contract you follow has been updated!',
                html_template='conductor/emails/new_contract.html',
                contract=main_contract
            ).send(multi=True)

            session.pop('contract')
            session.pop('companies')
            session['success'] = True

            current_app.logger.info('''
                CONDUCTOR CONTRACT COMPLETE - company contacts for contract "{}" assigned.
                New contract(s) successfully created'''.format(
                contract.description
            ))

            return redirect(url_for('conductor.success', contract_id=main_contract.id))

        if len(form.companies.entries) == 0:
            for company in companies:
                form.companies.append_entry()

        return render_template(
            'conductor/edit/edit_company_contacts.html', form=form, contract=contract,
            companies=companies
        )
    elif session.get('contract') is None:
        return redirect(url_for('conductor.edit', contract_id=contract_id))
    elif session.get('companies') is None:
        return redirect(url_for('conductor.edit_company', contract_id=contract_id))
    abort(404)