예제 #1
0
def not_reseller_customer(func, *args, **kwargs):
    """
    Ensure project isn't a resold customer
    """
    request = args[1]
    project_id = request.keystone_user['project_id']

    odooclient = odoo_client.get_odoo_client()

    try:
        odoo_project = odooclient.projects.list(
            [('tenant_id', '=', project_id)], read=True)[0]
    except IndexError:
        return Response({'errors': ['Project not found']}, status=404)

    reseller_customer_rels = odooclient.project_relationships.list(
        [('cloud_tenant', '=', odoo_project['id']),
         ('contact_type', '=', 'reseller customer')],
        read=True)

    if reseller_customer_rels:
        return Response(
            {
                'errors': ['Reseller customers cannot access this API.'],
                'is_reseller_customer': True
            }, 403)

    return func(*args, **kwargs)
예제 #2
0
    def _link_individual(self):
        partner_id = self.action.task.cache.get('partner_id')
        odoo_project_id = self.get_cache('odoo_project_id')
        odoo_client = get_odoo_client()

        owner_rel = self.get_cache('owner_rel')
        if not owner_rel:
            owner_rel = odoo_client.project_relationships.create(
                cloud_tenant=odoo_project_id,
                partner_id=partner_id,
                contact_type="owner")
            self.set_cache('owner_rel', owner_rel)

        primary_id = self.action.task.cache.get('primary_id')

        primary_rel = self.get_cache('primary_rel')
        if not primary_rel:
            primary_rel = odoo_client.project_relationships.create(
                cloud_tenant=odoo_project_id,
                partner_id=primary_id,
                contact_type="primary")
            self.set_cache('primary_rel', primary_rel)

        billing_rel = self.get_cache('billing_rel')
        if primary_id and not billing_rel:
            billing_rel = odoo_client.project_relationships.create(
                cloud_tenant=odoo_project_id,
                partner_id=primary_id,
                contact_type="billing")
            self.set_cache('billing_rel', billing_rel)
예제 #3
0
    def _create_initial_credit(self):
        # floating point dollar amount
        credit_amount = float(self.settings.get(
            'initial_credit_amount', 0))
        # in days
        credit_duration = int(self.settings.get('credit_duration', 0))
        if credit_amount > 0 and credit_duration > 0:
            odoo_project_id = self.get_cache('odoo_project_id')
            # id in odoo, default is 'Cloud Trial Credit '
            credit_type_id = int(self.settings.get('credit_type_id', 1))
            credit_code = self.settings.get(
                'credit_code', 'initial_credit')

            now = timezone.now()
            expiry_date = now + timedelta(days=credit_duration)

            odoo_client = get_odoo_client()
            credit_id = odoo_client.credits.create(
                cloud_tenant=odoo_project_id,
                code=credit_code,
                credit_type_id=credit_type_id,
                initial_balance=credit_amount,
                current_balance=credit_amount,
                start_date=now.isoformat(),
                expiry_date=expiry_date.isoformat(),
            )
            self.set_cache('credit_id', credit_id)
예제 #4
0
    def _validate_organisation(self):
        odoo_client = get_odoo_client()

        customers = odoo_client.partners.fuzzy_match(
            name=self.company_name, is_company=True)

        if len(customers) > 0:
            for customer in customers:
                if customer['match'] == 1:
                    self.add_note(
                        "Exact company exists: %s" % customer['name'])
                    self._validate_similar_organisation(customer)
                else:
                    self.add_note(
                        "Similar company exists: %s" % customer['name'])
                    self._validate_similar_organisation(customer)

            # We set the name to something obvious in odoo
            self.odoo_company_name = (
                "%s - (POSSIBLE DUPLICATE)" % self.company_name)
            self.add_note(
                "Rather than reuse existing will create duplicate as: '%s'" %
                self.odoo_company_name)
            self.add_note(
                "Needs Manual merge if was correct match, or rename if not.")
            return True
        else:
            self.add_note(
                "No existing company with name '%s'." %
                self.company_name)
            self.odoo_company_name = self.company_name
            return True
예제 #5
0
    def get(self, request):
        """ View Account Details """
        odooclient = odoo_client.get_odoo_client()
        project_id = request.keystone_user['project_id']

        project_search = [('tenant_id', '=', project_id)]

        try:
            odoo_project_id = odooclient.projects.list(project_search,
                                                       read=True)[0]['id']
        except IndexError:
            return Response({'errors': ['Project not found']}, status=404)

        search = [
            ("cloud_tenant", "=", odoo_project_id),
            ("contact_type", "=", "owner"),
        ]
        owner_id = odooclient.project_relationships.list(
            search, read=True)[0]['partner_id'][0]
        owner = odooclient.partners.get(owner_id, read=True)[0]
        address = get_address_dict(owner)

        account_type = 'organisation'
        individual_tag_id = settings.PLUGIN_SETTINGS.get(
            'adjutant-odoo', {}).get("individual_tag_id", None)
        if individual_tag_id in [tag for tag in owner['category_id']]:
            account_type = 'individual'

        project_tasks = Task.objects.filter(
            project_id=project_id,
            task_type=AccountDetailsManagement.task_type,
            completed=0,
            cancelled=0).order_by('-created_on')

        address_tasks = []

        for task in project_tasks:
            task_data = {}
            for action in task.actions:
                task_data.update(action.action_data)

            if task_data['country'] != address['country']:
                address_tasks.append(task_data)

        # TODO(adriant): include if is root project (as can only edit address
        # for root projects)
        response_dict = {
            'account_type': account_type,
            'address': address,
            'customer_name': owner['name'],
            'is_root_project': is_root_project(project_id),
        }

        if address_tasks:
            response_dict['pending_details'] = address_tasks[0]
        return Response(response_dict)
예제 #6
0
 def _validate_primary_country(self):
     odooclient = get_odoo_client()
     try:
         self.country_id = odooclient.countries.get_closest_country(
             self.country).id
         self.add_note("Found country %s" % self.country)
         return True
     except IndexError:
         self.add_note("Did not find country %s" % self.country)
         return False
예제 #7
0
    def _update_partner(self, partner):
        """Update the name and address fields on the given partner

        Expects:
            - self.name
            - self.address_1
            - self.address_2
            - self.city
            - self.postal_code
            - self.country_id
        """
        odooclient = odoo_client.get_odoo_client()

        name_changed = partner.name != self.name

        address_changed = any([
            partner.street != self.address_1,
            partner.street2 != self.address_2,
            partner.city != self.city,
            partner.zip != self.postal_code,
            partner.country_id != self.country_id,
        ])

        message_str = ""

        if name_changed:
            message_str += ("<dt>Partner has changed their name from:</dt>"
                            "<dd>%s</dd><dt>to</dt><dd>%s</dd>" %
                            (partner.name, self.name))

        if address_changed:
            message_str += (
                "<dt>Partner address has changed. Prior address was: </dt>"
                "<dd>%s</dd><dd>%s</dd><dd>%s, %s</dd><dd>%s</dd>" %
                (partner.street, partner.street2, partner.city, partner.zip,
                 partner.country_id.name))

        odooclient.partners.add_internal_note(partner.id, message_str)

        # Turn auto_commit off briefy to increase speed
        odooclient._odoorpc.config['auto_commit'] = False
        partner.name = self.name
        partner.street = self.address_1
        partner.street2 = self.address_2
        partner.city = self.city
        partner.zip = self.postal_code
        partner.country_id = self.country_id

        self.add_note("Updated address of partner '%s'" % partner.name)
        partner.env.commit()

        odooclient._odoorpc.config['auto_commit'] = True
예제 #8
0
def get_address_dict(odoo_owner):
    odooclient = odoo_client.get_odoo_client()
    if odoo_owner['country_id']:
        country = odooclient.countries.get(odoo_owner['country_id'][0],
                                           read=True)[0]
    else:
        country = {}
    return {
        'address_1': odoo_owner['street'] or "",
        'address_2': odoo_owner['street2'] or "",
        'postal_code': odoo_owner['zip'] or "",
        'city': odoo_owner['city'] or "",
        'country': country.get('code', ""),
        'country_name': country.get('name', ""),
    }
예제 #9
0
    def _validate_partner_exists(self):
        """ Validates that a partner with the given id exists in odoo

        Expects:
            - self.partner_id
        Sets:
            - self.partner
        """
        odooclient = odoo_client.get_odoo_client()
        try:
            self.partner = odooclient.partners.get(self.partner_id)[0]
            self.add_note('Contact id %s exists. (%s)' %
                          (self.partner_id, self.partner.name))
            return True
        except IndexError:
            self.add_note('Partner with id %s does not exist.' %
                          self.partner_id)
        return False
예제 #10
0
    def _create_odoo_project(self, project_id):
        odoo_client = get_odoo_client()

        try:
            id_manager = user_store.IdentityManager()

            project = id_manager.get_project(project_id)

            odoo_project_id = odoo_client.projects.create(
                name=project.name,
                tenant_id=project.id)

            # set a flag to tell us we've created the project in Odoo.
            self.set_cache('odoo_project_id', odoo_project_id)
        except Exception as e:
            self.add_note(
                "Error: '%s' while linking project: %s in Odoo." %
                (e, project_id))
            raise
예제 #11
0
    def _get_odoo_project_owner(self):
        """
        Get the project owner partner.

        Expects:
            - self.project_id
        Sets:
            - self.odoo_project = <odoo project browsable model>
            - self.project_owner = <odoo partner browsable model>
        Returns: <odoo partner browsable model>
        """
        if not getattr(self, 'project_owner', None):
            odooclient = odoo_client.get_odoo_client()

            projects = odooclient.projects.list([('tenant_id', '=',
                                                  self.project_id)])
            if len(projects) == 0:
                raise OdooModelsIncorrect(
                    'Project "%s" is not set up in OpenERP.' % self.project_id)
            if len(projects) > 1:
                raise OdooModelsIncorrect(
                    'More than one project "%s" is set up in OpenERP.' %
                    self.project_id)

            self.odoo_project = projects[0]
            self.add_note("Odoo Project ID: %s" % self.odoo_project.id)

            project_rels = odooclient.project_relationships.list([
                ('cloud_tenant', '=', self.odoo_project.id),
                ('contact_type', '=', 'owner'),
            ])

            if len(project_rels) == 0:
                raise OdooModelsIncorrect('Project "%s" has no owner!' %
                                          self.project_id)
            elif len(project_rels) > 1:
                raise OdooModelsIncorrect(
                    'Project "%s" has more than one owner!' % self.project_id)

            self.project_owner = project_rels[0].partner_id

        self.add_note("Found owner: %s" % self.project_owner.name)
        return self.project_owner
예제 #12
0
    def _validate_country_exists(self):
        """
        Takes a country name (self.country) and attempts to find a
        fuzzy match for it (self.country_id)

        Expects:
            - self.country
        Sets:
            - self.country_id
        """
        odooclient = odoo_client.get_odoo_client()
        try:
            self.country_id = odooclient.countries.get_closest_country(
                self.country)
            self.add_note("Found country %s" % self.country_id.name)
            return True
        except IndexError:
            self.add_note("Did not find country %s" % self.country)
            return False
예제 #13
0
    def _validate_similar_organisation(self, customer):
        odoo_client = get_odoo_client()

        company = odoo_client.partners.get(customer['id'])[0]

        tags = [tag.id for tag in company.category_id]
        if self.cloud_tag_id and self.cloud_tag_id in tags:
            self.add_note(
                "Company: %s has cloud tag." % customer['name'])
        elif self.cloud_tag_id:
            self.add_note(
                "Company: %s does not have cloud tag." % customer['name'])

        contacts = odoo_client.partners.fuzzy_match(
            name=self.name, check_parent=True,
            parent=customer['id'])

        for contact in contacts:
            if contact['match'] == 1:
                self.add_note(
                    "Primary contact: %s found for company: %s" %
                    (contact['name'], customer['name']))
            else:
                self.add_note(
                    "Similar primary contact: %s found for company: %s" %
                    (contact['name'], customer['name']))

        if not self.primary_contact_is_billing:
            contacts = odoo_client.partners.fuzzy_match(
                name=self.bill_name, check_parent=True,
                parent=customer['id'])

            for contact in contacts:
                if contact['match'] == 1:
                    self.add_note(
                        "Billing contact: %s found for company: %s" %
                        (contact['name'], customer['name']))
                else:
                    self.add_note(
                        "Similar billing contact: %s found for company: %s" %
                        (contact['name'], customer['name']))
예제 #14
0
    def _validate_individual(self):
        odoo_client = get_odoo_client()

        customers = odoo_client.partners.fuzzy_match(name=self.name)
        if len(customers) > 0:
            for customer in customers:
                if customer['match'] == 1:
                    self.add_note(
                        "Exact customer already exists: %s" % self.name)
                else:
                    self.add_note(
                        "Similar customer already exists: %s" % self.name)

            self.customer_name = ("%s - (POSSIBLE DUPLICATE)" % self.name)
            self.add_note(
                "Rather than reuse existing will create duplicate as: '%s'" %
                self.customer_name)
            return True
        else:
            self.add_note(
                "No existing customer with name: %s" % self.name)
            self.customer_name = ("%s" % self.name)
            return True
예제 #15
0
    def _get_parent_id(self):
        """Get ID of the owner (company) for the project

        Expects:
            - self.project_id
            - self.odoo_project_id
        Sets:
            - self.odoo_owner
        """
        if getattr(self, 'odoo_owner', None):
            return self.odoo_owner.id

        odooclient = odoo_client.get_odoo_client()
        search = [['cloud_tenant', '=', self.odoo_project_id],
                  ['contact_type', '=', 'owner']]
        all_relations = odooclient.project_relationships.list(search)
        if len(all_relations) > 1:
            note = ("WARNING! More than one owner found for '%s'" %
                    self.project_id)
            self.add_note(note)
            if not self.get_cache('multi_owner_error'):
                create_notification(self.action.task, {'errors': [note]},
                                    error=True)
                self.set_cache('multi_owner_error', True)

        if len(all_relations) < 1:
            note = ("WARNING! No owner found for '%s'" % self.project_id)
            self.add_note(note)
            if not self.get_cache('no_owner_error'):
                create_notification(self.action.task, {'errors': [note]},
                                    error=True)
                self.set_cache('no_owner_error', True)
            return None

        self.odoo_owner = all_relations[0].partner_id
        self.add_note("Found owner: %s" % self.odoo_owner.name)
        return self.odoo_owner.id
예제 #16
0
    def _validate_project_exists(self):
        """ Validates a project exists in odoo

        Expects:
            - self.project_id
        Sets:
            - self.odoo_project = <odoo project browsable model>
            - self.odoo_project_id
            - self.odoo_project_name
        """
        odooclient = odoo_client.get_odoo_client()
        try:
            search = [['tenant_id', '=', self.project_id]]
            project = odooclient.projects.list(search)[0]
            self.odoo_project = project
            self.odoo_project_id = project.id
            self.odoo_project_name = project.name
            self.add_note('Odoo project %s (%s) exists.' %
                          (self.odoo_project_name, self.odoo_project_id))
            return True
        except IndexError:
            self.add_note('Project %s does not exist in odoo' %
                          self.project_id)
        return False
예제 #17
0
    def _create_individual(self):
        odoo_client = get_odoo_client()

        partner_id = self.get_cache('partner_id')
        if partner_id:
            self.add_note("Partner already created.")
        else:
            try:
                # TODO(adriant): store credit card somewhere
                # and flag customer with credit payment type
                partner_dict = {
                    'is_company': True,
                    'opt_out': True,
                    'name': self.customer_name,
                    'email': self.email,
                    'phone': self.phone,
                    'street': self.bill_address_1,
                    'street2': self.bill_address_2,
                    'city': self.bill_city,
                    'zip': self.bill_postal_code,
                    'country_id': self.bill_country_id,
                }

                tags = []
                if self.cloud_tag_id:
                    tags.append(self.cloud_tag_id)
                if self.individual_tag_id:
                    tags.append(self.individual_tag_id)
                if tags:
                    partner_dict['category_id'] = [(6, 0, tags)]

                if self.set_fiscal_position:
                    partner_dict['property_account_position'] = \
                        self.fiscal_position_id
                partner_id = odoo_client.partners.create(**partner_dict)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while setting up partner in Odoo." % e)
                raise
            self.set_cache('partner_id', partner_id)
            self.add_note("Partner '%s' created." % self.customer_name)
        self.action.task.cache['partner_id'] = partner_id

        # Now we handle the primary contact for the new project:
        primary_id = self.get_cache('primary_id')
        if primary_id:
            self.add_note("Primary contact already created.")
        else:
            try:
                primary_id = odoo_client.partners.create(
                    is_company=False, opt_out=(not self.news_agreed),
                    name=self.name,
                    email=self.email, phone=self.phone,
                    parent_id=partner_id,
                    use_parent_address=True)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while setting up "
                    "primary contact in Odoo." % e)
                raise
            self.set_cache('primary_id', primary_id)
            self.add_note("Primary contact '%s' created." % self.name)
        self.action.task.cache['primary_id'] = primary_id
예제 #18
0
    def _create_organisation(self):
        odoo_client = get_odoo_client()

        # First we handle the company.
        # In this context partner is the company:
        partner_id = self.get_cache('partner_id')
        if partner_id:
            self.add_note(
                "Partner already created with id: %s." % partner_id)
        else:
            try:
                # TODO(adriant): store credit card somewhere
                # and flag customer with credit payment type
                partner_dict = {
                    'is_company': True,
                    'opt_out': True,
                    'name': self.odoo_company_name,
                }
                if self.primary_contact_is_billing:
                    partner_dict['email'] = self.email
                else:
                    partner_dict['email'] = self.bill_email

                if self.primary_address_is_billing:
                    partner_dict['street'] = self.address_1
                    partner_dict['street2'] = self.address_2
                    partner_dict['city'] = self.city
                    partner_dict['zip'] = self.postal_code
                    partner_dict['country_id'] = self.country_id
                else:
                    partner_dict['street'] = self.bill_address_1
                    partner_dict['street2'] = self.bill_address_2
                    partner_dict['city'] = self.bill_city
                    partner_dict['zip'] = self.bill_postal_code
                    partner_dict['country_id'] = self.bill_country_id

                if self.cloud_tag_id:
                    partner_dict['category_id'] = \
                        [(6, 0, [self.cloud_tag_id])]
                if self.set_fiscal_position:
                    partner_dict['property_account_position'] = \
                        self.fiscal_position_id
                partner_id = odoo_client.partners.create(**partner_dict)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while setting up partner in Odoo." % e)
                raise
            self.set_cache('partner_id', partner_id)
            self.add_note("Partner '%s' created." % self.odoo_company_name)
        self.action.task.cache['partner_id'] = partner_id

        if not self.primary_address_is_billing:
            physical_address_id = self.get_cache('physical_address_id')
            if physical_address_id:
                self.add_note("Physical address contact already created.")
            else:
                try:
                    physical_address_id = odoo_client.partners.create(
                        is_company=False,
                        opt_out=True,
                        name=self.physical_address_contact_name,
                        street=self.address_1,
                        street2=self.address_2,
                        city=self.city, zip=self.postal_code,
                        country_id=self.country_id,
                        parent_id=partner_id)
                except Exception as e:
                    self.add_note(
                        "Error: '%s' while setting up "
                        "physical address contact in Odoo." % e)
                    raise
                self.set_cache('physical_address_id', physical_address_id)
                self.add_note("Physical address contact '%s' created." %
                              self.physical_address_contact_name)
            self.action.task.cache['physical_address_id'] = physical_address_id

        # Now we handle the primary contact for the new project:
        primary_id = self.get_cache('primary_id')
        if primary_id:
            self.add_note("Primary contact already created.")
        else:
            try:
                primary_id = odoo_client.partners.create(
                    is_company=False, opt_out=(not self.news_agreed),
                    name=self.name,
                    email=self.email, phone=self.phone,
                    parent_id=partner_id,
                    use_parent_address=True)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while setting up "
                    "primary contact in Odoo." % e)
                raise
            self.set_cache('primary_id', primary_id)
            self.add_note("Primary contact '%s' created." % self.name)
        self.action.task.cache['primary_id'] = primary_id

        billing_id = self.get_cache('billing_id')
        if billing_id:
            self.add_note("Billing contact already created.")
        elif self.primary_contact_is_billing:
            billing_id = primary_id
        elif not self.primary_contact_is_billing:
            try:
                billing_id = odoo_client.partners.create(
                    is_company=False, opt_out=True, name=self.bill_name,
                    email=self.bill_email, parent_id=partner_id)
            except Exception as e:
                self.add_note(
                    "Error: '%s' while setting up "
                    "billing contact in Odoo." % e)
                raise
            self.set_cache('billing_id', billing_id)
            self.add_note("Billing contact '%s' created." % self.bill_name)
        self.action.task.cache['billing_id'] = billing_id