Reuse Address and Contact in Custom Frappe App

I am working on a custom frappe app and I am trying to achieve something really simple. To reuse Address and Contact as seen on some ERPNext DocTypes.

I have included the necessary fields in my custom DocType Organization. I have also done the following:

in organization.py:

from future import unicode_literals

import frappe

import frappe

from frappe.model.document import Document

from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address

class Organization(Document):

def onload(self):

    """Load address and contacts in `__onload`"""

    load_address_and_contact(self)

def on_update(self):

    self.create_primary_contact()

    self.create_primary_address()

def on_trash(self):

    delete_contact_and_address('Organization', self.name)

def create_primary_contact(self):

    if not self.org_primary_contact:

        if self.mobile_no or self.email_id:

            contact = make_contact(self)

            self.db_set('org_primary_contact', contact.name)

            self.db_set('mobile_no', self.mobile_no)

            self.db_set('email_id', self.email_id)

def create_primary_address(self):

    if self.flags.is_new_doc and self.get('address_line1'):

        make_address(self)

def make_contact(args, is_primary_contact=1):

    contact = frappe.get_doc({

        'doctype': 'Contact',

        'first_name': args.get('name'),

        'is_primary_contact': is_primary_contact,

        'links': [{

            'link_doctype': args.get('doctype'),

            'link_name': args.get('name')

        }]

    })

    if args.get('email_id'):

        contact.add_email(args.get('email_id'), is_primary=True)

    if args.get('mobile_no'):

        contact.add_phone(args.get('mobile_no'), is_primary_mobile_no=True)

    contact.insert()

    return contact

def make_address(args, is_primary_address=1):

    reqd_fields = []

    for field in ['city', 'country']:

        if not args.get(field):

            reqd_fields.append( '<li>' + field.title() + '</li>')

    if reqd_fields:

        msg = _("Following fields are mandatory to create address:")

        frappe.throw("{0} <br><br> <ul>{1}</ul>".format(msg, '\n'.join(reqd_fields)),

            title = _("Missing Values Required"))

    address = frappe.get_doc({

        'doctype': 'Address',

        'address_title': args.get('name'),

        'address_line1': args.get('address_line1'),

        'address_line2': args.get('address_line2'),

        'city': args.get('city'),

        'state': args.get('state'),

        'pincode': args.get('pincode'),

        'country': args.get('country'),

        'links': [{

            'link_doctype': args.get('doctype'),

            'link_name': args.get('name')

        }]

    }).insert()

    return address

@frappe.whitelist()

@frappe.validate_and_sanitize_search_inputs

def get_primary_contact(doctype, txt, searchfield, start, page_len, filters):

organization = filters.get('organization')

return frappe.db.sql("""

    select `tabContact`.name from `tabContact`, `tabDynamic Link`

        where `tabContact`.name = `tabDynamic Link`.parent and `tabDynamic Link`.link_name = %(organization)s

        and `tabDynamic Link`.link_doctype = 'Organization'

        and `tabContact`.name like %(txt)s

    """, {

        'organization': organization,

        'txt': '%%%s%%' % txt

    }) 

and in organization.js

frappe.ui.form.on(‘Organization’, {

setup: function(frm) {

  frm.set_query('org_primary_contact', function(doc) {

    return {

      query: "cpm.setup.doctype.organization.organization.get_primary_contact",

      filters: {

        'organization': doc.name

      }

    }

  })

  frm.set_query('org_primary_address', function(doc) {

    return {

      filters: {

        'link_doctype': 'Organization',

        'link_name': doc.name

      }

    }

  });

},

refresh: function(frm) {

  frappe.dynamic_link = {doc: frm.doc, fieldname: 'org_name', doctype: 'Organization'}

  frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);

  if(!frm.doc.__islocal) {

    frappe.contacts.render_address_and_contact(frm);

  } else {

    frappe.contacts.clear_address_and_contact(frm);

  }

},

party_primary_address: function(frm){

  if(frm.doc.org_primary_address){

    frappe.call({

      method: 'frappe.contacts.doctype.address.address.get_address_display',

      args: {

        "address_dict": frm.doc.org_primary_address

      },

      callback: function(r) {

        frm.set_value("primary_address", r.message);

      }

    });

  }

  if(!frm.doc.org_primary_address){

    frm.set_value("primary_address", "");

  }

},

party_primary_contact: function(frm){

  if(!frm.doc.org_primary_contact){

    frm.set_value("mobile_no", "");

    frm.set_value("email_id", "");

  }

},

});

Still the Add new Contact and Add new Address buttons are not rendering. Also Primary Contact filter raises the error

AttributeError: module ‘cpm.setup.doctype.organization.organization’ has no attribute ‘get_primary_contact’

What am I doing wrong here? Help please. Thanks.