def create_from_oc(site_name, customer_id, oc_order=None):
    if oc_order:
        customer_id = oc_order.get('customer_id')

    success, oc_customer = oc_api.get(site_name).get_customer(customer_id)

    if not success:
        frappe.throw('Cannot get Customer from Opencart site. Error: %s' % oc_customer.get('error') or 'Unknown')

    customer_group_id = oc_customer.get('customer_group_id', '')
    doc_customer_group = customer_groups.get(site_name, customer_group_id)

    if not doc_customer_group:
        frappe.throw('Could not found Customer Group with customer_group_id "%s"' % customer_group_id)

    default_price_list = doc_customer_group.get('default_price_list')
    territory_name = territories.DEFAULT
    if oc_order:
        if oc_order.get('shipping_iso_code_3') and oc_order.get('shipping_zone_code'):
            territory_name = territories.get_by_iso_code3(oc_order.get('shipping_iso_code_3'), oc_order.get('shipping_zone_code'))
        else:
            territory_name = territories.get_by_iso_code3(oc_order.get('payment_iso_code_3'), oc_order.get('payment_zone_code'))
    # create new Customer
    params = {
        'doctype': 'Customer',
        'customer_type': 'Individual',
        'territory': territory_name,
        'customer_name': make_full_name(oc_order.get('firstname'), oc_order.get('lastname')),
        'customer_group': doc_customer_group.get('name'),
        'naming_series': 'CUST-',
        'default_price_list': default_price_list,
        'oc_guest': 0,
        'oc_is_updating': 1,
        'oc_site': site_name,
        'oc_customer_id': customer_id,
        'oc_store_id': oc_customer.get('store_id') or '',
        'oc_status': 1,
        'oc_sync_from': True,
        'oc_last_sync_from': datetime.now(),
        'oc_sync_to': True,
        'oc_last_sync_to': datetime.now(),
        'oc_firstname': oc_order.get('firstname'),
        'oc_lastname': oc_order.get('lastname'),
        'oc_telephone': oc_order.get('telephone'),
        'oc_fax': oc_order.get('fax'),
        'oc_email': oc_order.get('email')
    }
    doc_customer = frappe.get_doc(params)
    doc_customer.insert(ignore_permissions=True)

    # addresses and contacts
    addresses.create_or_update(site_name, oc_customer, doc_customer)
    contacts.create_or_update(site_name, oc_customer, doc_customer)
    if oc_order:
        # addresses and contacts
        addresses.create_or_update_from_order(site_name, doc_customer, oc_order)
        contacts.create_or_update_from_order(site_name, doc_customer, oc_order)

    return doc_customer
def pull_customers_from_oc(site_name, silent=False):
    '''Sync customers from Opencart site'''
    results = {}
    results_list = []
    check_count = 0
    update_count = 0
    add_count = 0
    skip_count = 0
    success = False

    site_doc = frappe.get_doc('Opencart Site', site_name)
    # root_customer_group = site_doc.get('root_customer_group')
    default_customer_territory = site_doc.get('default_customer_territory') or 'All Territories'
    doc_customer_groups_cache = {}
    for success, oc_customer in oc_api.get(site_name).get_customers():
    # success, oc_customer = oc_api.get(site_name).get_customer('1332')
    # while True:
    #     if check_count >= 1:
    #         break
        check_count += 1

        oc_customer_name = make_full_name(oc_customer.get('firstname'), oc_customer.get('lastname'))
        customer_id = oc_customer.get('customer_id')

        # validation
        # missed_mandatory_fields = [field for field in OC_MANDATORY_FIELDS if not oc_customer.get(field)]
        # if missed_mandatory_fields:
        #     skip_count += 1
        #     extras = (1, 'skipped', 'Skipped: mandatory fileds missed: %s' % ', '.join(missed_mandatory_fields))
        #     results_list.append((oc_customer_name, customer_id, '', '', '') + extras)
        #     continue

        doc_customer_group = doc_customer_groups_cache.get(oc_customer.get('customer_group_id'))
        if not doc_customer_group:
            doc_customer_group = customer_groups.get(site_name, oc_customer.get('customer_group_id'))
            doc_customer_groups_cache[oc_customer.get('customer_group_id')] = doc_customer_group

        if not doc_customer_group:
            skip_count += 1
            extras = (1, 'skipped', 'Skipped: parent group missed')
            results_list.append((oc_customer_name, customer_id, '', '', '') + extras)
            continue

        doc_customer = get_customer(site_name, customer_id)
        if doc_customer:
            # update existed Customer
            # check here for a need to update Customer
            params = {
                'customer_name': oc_customer_name,
                'customer_group': doc_customer_group.get('name'),
                'oc_last_sync_from': datetime.now(),
                'oc_is_updating': 1,
                'oc_store_id': oc_customer.get('store_id') or '',
                'oc_status': 1,
                'oc_firstname': oc_customer.get('firstname'),
                'oc_lastname': oc_customer.get('lastname'),
                'oc_telephone': oc_customer.get('telephone'),
                'oc_fax': oc_customer.get('fax'),
                'oc_email': oc_customer.get('email'),
            }
            doc_customer.update(params)
            doc_customer.save()

            # addresses and contacts
            addresses.create_or_update(site_name, oc_customer, doc_customer)
            contacts.create_or_update(site_name, oc_customer, doc_customer)

            update_count += 1
            extras = (1, 'updated', 'Updated')
            results_list.append((doc_customer.get('name'),
                                 doc_customer.get('oc_customer_id'),
                                 doc_customer_group.get('name'),
                                 doc_customer.get_formatted('oc_last_sync_from'),
                                 doc_customer.get('modified')) + extras)

        else:
            default_price_list = doc_customer_group.get('default_price_list')
            # do not allow to aad new customer if default_price_list is missed in customer's group
            # if not default_price_list:
            #     skip_count += 1
            #     extras = (1, 'skipped', 'Skipped: missed default price list in customer group')
            #     results_list.append((oc_customer_name, customer_id, '', '', '') + extras)
            #     continue

            # create new Customer
            params = {
                'doctype': 'Customer',
                'customer_type': 'Individual',
                'territory': default_customer_territory,
                'customer_name': oc_customer_name,
                'customer_group': doc_customer_group.get('name'),
                'naming_series': 'CUST-',
                'default_price_list': default_price_list,
                'oc_is_updating': 1,
                'oc_site': site_name,
                'oc_customer_id': customer_id,
                'oc_store_id': oc_customer.get('store_id') or '',
                'oc_status': 1,
                'oc_sync_from': True,
                'oc_last_sync_from': datetime.now(),
                'oc_sync_to': True,
                'oc_last_sync_to': datetime.now(),
                'oc_firstname': oc_customer.get('firstname'),
                'oc_lastname': oc_customer.get('lastname'),
                'oc_telephone': oc_customer.get('telephone'),
                'oc_fax': oc_customer.get('fax'),
                'oc_email': oc_customer.get('email')
            }
            doc_customer = frappe.get_doc(params)
            if not doc_customer.get('customer_name').strip():
                continue
            doc_customer.insert(ignore_permissions=True)

            # addresses and contacts
            addresses.create_or_update(site_name, oc_customer, doc_customer)
            contacts.create_or_update(site_name, oc_customer, doc_customer)

            add_count += 1
            extras = (1, 'added', 'Added')
            results_list.append((doc_customer.get('customer_name'),
                                 doc_customer.get('oc_customer_id'),
                                 doc_customer_group.get('name'),
                                 doc_customer.get_formatted('oc_last_sync_from'),
                                 doc_customer.get('modified')) + extras)
    results = {
        'check_count': check_count,
        'add_count': add_count,
        'update_count': update_count,
        'skip_count': skip_count,
        'results': results_list,
        'success': success,
    }
    return results