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)
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)
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)
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
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)
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
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
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', ""), }
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
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
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
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
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']))
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
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
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
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
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