def match_with_existing_partner(obj,cr,uid,vals):
    """
    when we could not find a partner by its unique identifier = email
    we do an extra check if we can find it based on address and name
    """
    def concat_names(p):
        try:
            return p.first_name + '_' + p.last_name
        except:
            return ''

    def match_on_fullname(target_ids):
        match_target_list = []
        for partner in obj.browse(cr,uid,target_ids):
            match_target_list.append((partner.id, concat_names(partner)))
        return difflib_cmp(concat_names(ref_vals), match_target_list)[0] if match_target_list else False

    def match_names_seperatly(cmp_res):
        """
        return tuple partner object,boolean full match
        """
        _logger.info("partner fullname match diff:{}".format(cmp_res))
        if cmp_res:
            partner = obj.browse(cr,uid,cmp_res[0])
            if cmp_res[1] == 1.0:
                return (partner,True)
            if cmp_res[1] > 0.5:
                first_name = partner.first_name if partner.first_name else ''
                cmp_res_first_name = difflib_cmp(ref_vals.first_name, [(partner.id, first_name)])[0]
                last_name =  partner.last_name if partner.last_name else ''
                cmp_res_last_name = difflib_cmp(ref_vals.last_name, [(partner.id, last_name)])[0]
                _logger.info("partner firstname match diff:{}".format(cmp_res_first_name))
                _logger.info("partner lastname match diff:{}".format(cmp_res_last_name))
                # rules, priority full match to less match
                rules = [lambda f,l : f == 0 and l == 1.0,    # no firstname, 100% lastname
                         lambda f,l : f >= 0.7 and l >= 0.85] # seperate firstname/lastname
                res = [func(cmp_res_first_name[1],cmp_res_last_name[1]) for func in rules]
                # return partner,full match or partial match
                return (partner,res[0]) if any(res) else (False,False)
            else:
                return (False,False)
        else:
            return (False,False)

    ref_vals = get_match_vals(vals)
    if 'street_id' in vals and vals['street_id']:
       target_domain = [
            ('street_id','=',vals['street_id']),
            ('zip_id','=',vals['zip_id']),
            ('street_nbr','=',vals['street_nbr']),
       ]
    else:
       target_domain = [
            ('street','=',vals['street']),
            ('zip','=',vals['zip']),
            ('street_nbr','=',vals['street_nbr']),
       ]
    partner = compose(
                match_on_fullname,
                match_names_seperatly,
                lambda (p,full_match): p if p and (not(p.donation_line_ids) or full_match) else False
              )(obj.search(cr,uid,target_domain))
    log = {'alert':['Lidmaatschap aanvraag naam match'] if partner else [],'renewal':False}
    return (partner if partner else False, vals, log)
    def create_web_membership(self,cr,uid,ids,vals,datas,context=None):
        context = context or {}
        if ids == None:
            ids = []

        # membership_origin_id                    
        membership_origin_id = datas.get('membership_origin_id', 0)
        if self._verify_membership_origin(cr,uid,[membership_origin_id],context=context):
            vals['membership_origin_id'] = membership_origin_id

        # recruiting_organisation_id
        recruiting_organisation_id = datas.get('recruiting_organisation_id', 0)
        if not(self._verify_recruiting_organisation(cr,uid,[recruiting_organisation_id],context=context)):
            datas.pop('recruiting_organisation_id', None)

        # convert website membership + subscriptions to product
        product_id = self._web_membership_product(cr,uid,datas['subscriptions'],context=context)

        # renewal product...? , update contact  
        if datas.get('membership_renewal', False):
            vals['membership_renewal_product_id'] = product_id

        # override default from website            
        vals['customer'] = False

        # membership partner update or create
        _logger.info(vals)
        if not ids:
            _logger.info("partner niet aangemeld")
            ids,vals,log = compose(
                    partial(match_with_existing_partner,self,cr,uid),
                    partial(verify_partner_membership_state,self,cr,uid),
                    partial(verify_if_customer_or_supplier,self,cr,uid),
                    partial(send_internal_alerts,self,cr,uid),
                    lambda (p,v,l):([p.id],v,l) if p else (ids,v,l)
            )(vals)
            _logger.info("partner match ids:{}".format(ids))
        else:
            _logger.info("partner aangemeld ids:{}".format(ids))
            log = {
                'alert':[],
                'renewal':datas.get('membership_renewal', False)
            }
            ids,vals,log = compose(
                    lambda ids:(self.browse(cr,uid,ids[0],context=context),vals,log),
                    partial(verify_if_customer_or_supplier,self,cr,uid),
                    partial(send_internal_alerts,self,cr,uid),
                    lambda (p,v,l):([p.id],v,l)
            )(ids)

        if 'alert_website' in log:
            _logger.info("website alert:{}".format(website_alert))
            return {'id':0,'alert_message':website_alert}
        else:
            ids = self._web_membership_partner(cr,uid,ids,vals,context=context)

        methods = {'OGONE':self.create_membership_invoice,
                   'SEPA':self.create_web_membership_mandate_invoice,
                   'OFFLINE':self.create_membership_invoice,}
        method = datas['method'].upper() if 'method' in datas else None
        if method in methods:
            inv_ids = methods[method](cr,uid,ids,selected_product_id=product_id,datas=datas,context=context)
        else:
            inv_ids = 0

        if inv_ids:
            invoice_obj = self.pool.get('account.invoice')
            for invoice in invoice_obj.browse(cr,uid,inv_ids,context=context):
                #ogone_log_obj = self.pool.get('ogone.log')
                #ogone_log_vals = {
                #    'invoice_id':invoice.id,
                #    'date_created':time.strftime('%Y-%m-%d %H:%M:%S'),
                #}
                #ogone_log_obj.create(cr, uid, ogone_log_vals, context=context)
                return {'id':invoice.partner_id.id,'invoice_id':invoice.id,'reference':invoice.reference}
        else:
            return {'id':ids[0]}