예제 #1
0
/*******************************************************************
 * fm_pymt_pol_collect_clear_pending():
 *******************************************************************/
static void
fm_pymt_pol_collect_clear_pending(
	pin_flist_t	*r_flistp,
	pin_decimal_t	*amount,
	char		*descr,
	pin_errbuf_t	*ebufp)
{
	pin_flist_t	*flistp = NULL;
	char		*action;
	int		count;

	if (PIN_ERR_IS_ERR(ebufp))
		return;
	PIN_ERR_CLEAR_ERR(ebufp);

	/***********************************************************
	 * Don't bother with zero amounts.
	 ***********************************************************/
	if (pbo_decimal_sign(amount, ebufp) == 0) {
		return;
		/*****/
	}

	/***********************************************************
	 * What elemid to add.
	 ***********************************************************/
	count = PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_ACTIVITIES, ebufp);

	/***********************************************************
	 * Add our element.
	 ***********************************************************/
	flistp = PIN_FLIST_ELEM_ADD(r_flistp, PIN_FLD_ACTIVITIES, count, ebufp);

	/***********************************************************
	 * Fill in our values.
	 ***********************************************************/
	action = "clear_pending";
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_ACTION, (void *)action, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_AMOUNT, (void *)amount, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp);

	return;
}
예제 #2
0
/*******************************************************************
 * fm_pymt_pol_collect_set_status():
 *******************************************************************/
static void
fm_pymt_pol_collect_set_status(
	pin_flist_t		*r_flistp,
	pin_status_t		status,
	int			flags,
	char			*descr,
	pin_errbuf_t		*ebufp)
{
	pin_flist_t		*flistp = NULL;
	char			*action;
	int			count;

	if (PIN_ERR_IS_ERR(ebufp))
		return;
	PIN_ERR_CLEAR_ERR(ebufp);

	/***********************************************************
	 * What elemid to add.
	 ***********************************************************/
	count = PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_ACTIVITIES, ebufp);

	/***********************************************************
	 * Add our element.
	 ***********************************************************/
	flistp = PIN_FLIST_ELEM_ADD(r_flistp, PIN_FLD_ACTIVITIES, count, ebufp);

	/***********************************************************
	 * Fill in our values.
	 ***********************************************************/
	action = "set_status";
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_ACTION, (void *)action, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS, (void *)&status, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS_FLAGS, (void *)&flags, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp);

	return;
}
/*******************************************************************
 * Main routine for the PCM_OP_ACT_POL_SPEC_GLID operation.
 *******************************************************************/
void
op_act_pol_spec_glid(
    cm_nap_connection_t	*connp,
    int			opcode,
    int			flags,
    pin_flist_t		*i_flistp,
    pin_flist_t		**r_flistpp,
    pin_errbuf_t		*ebufp)
{
    pin_cookie_t		cookie = NULL;
    pcm_context_t		*ctxp = connp->dm_ctx;
    pin_flist_t		*e_flistp = NULL;
    pin_flist_t		*s_flistp = NULL;
    pin_flist_t		*flistp = NULL;
    const char			*event_type = NULL;
    poid_t			*e_pdp = NULL;

    int			rec_id = 0;
    int			*glid = NULL;

    if (PIN_ERR_IS_ERR(ebufp))
        return;
    PIN_ERR_CLEAR_ERR(ebufp);
    *r_flistpp = (pin_flist_t *)NULL;

    /*******************************************************************
     * Insanity check.
     *******************************************************************/
    if (opcode != PCM_OP_ACT_POL_SPEC_GLID) {
        pin_set_err(ebufp, PIN_ERRLOC_FM,
                    PIN_ERRCLASS_SYSTEM_DETERMINATE,
                    PIN_ERR_BAD_OPCODE, 0, 0, opcode);
        PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
                         "op_act_pol_spec_glid bad opcode error", ebufp);
        return;
    }

    /*******************************************************************
     * Debug: What we got.
     *******************************************************************/
    PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,
                      "op_act_pol_spec_glid input flist", i_flistp);

    /*******************************************************************
     * Our action will depend on the type of event
     * Get the event substruct to get all the needed data
     *******************************************************************/
    *r_flistpp = PIN_FLIST_COPY(i_flistp, ebufp);
    e_flistp = PIN_FLIST_SUBSTR_GET(*r_flistpp, PIN_FLD_EVENT, 0, ebufp);
    e_pdp = (poid_t *)PIN_FLIST_FLD_GET(e_flistp, PIN_FLD_POID, 0, ebufp);
    event_type = PIN_POID_GET_TYPE(e_pdp);

    /******************************************************************
     * Check PIN_FLD_RATES_USED array, add a dummy one if not.
     ******************************************************************/
    if (PIN_FLIST_ELEM_COUNT(e_flistp, PIN_FLD_BAL_IMPACTS, ebufp) == 0) {

        /**********************************************************
         * Add the bal impacts array for this pre-rates event.
         **********************************************************/
        fm_act_pol_add_event_bal_impacts(ctxp, e_flistp, ebufp);
    }

    /******************************************************************
     * Now walk the PIN_FLD_RATES_USED array and check for G/L ID.
     ******************************************************************/
    while ((flistp = PIN_FLIST_ELEM_GET_NEXT(e_flistp, PIN_FLD_BAL_IMPACTS,
                     &rec_id, 1, &cookie, ebufp)) != (pin_flist_t *)NULL) {

        /**********************************************************
         * G/L id is inside the PIN_FLD_SUBTOTAL array.
         **********************************************************/
        glid = (int *)PIN_FLIST_FLD_GET(flistp,
                                        PIN_FLD_GL_ID, 1, ebufp);

        /**********************************************************
         * We need to fill in the G/L id now.
         **********************************************************/
        if (glid == (int *)NULL) {
            fm_act_pol_spec_glid(connp, i_flistp,
                                 event_type, flistp, ebufp);
        }
    }

    /*******************************************************************
     * Error?
     *******************************************************************/
    if (PIN_ERR_IS_ERR(ebufp)) {
        PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
                         "op_act_pol_spec_glid error", ebufp);
    } else {
        PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,
                          "op_act_pol_spec_glid return flist", *r_flistpp);
    }

    return;
}
/*******************************************************************
 * fm_act_pol_add_event_bal_impacts():
 *******************************************************************/
void
fm_act_pol_add_event_bal_impacts(
    pcm_context_t		*ctxp,
    pin_flist_t		*a_flistp,
    pin_errbuf_t		*ebufp)
{
    pin_cookie_t		cookie = NULL;
    pin_flist_t		*bi_flistp = NULL;
    pin_flist_t		*flistp = NULL;
    pin_flist_t		*bia_flistp = NULL;
    poid_t			*r_pdp = NULL;
    void			*vp = NULL;

    int			impact_type = 0;
    int			count = 0;
    int			rec_id = 0;
    pin_decimal_t 		*dummyp = NULL;

    if (PIN_ERR_IS_ERR(ebufp))
        return;
    PIN_ERR_CLEAR_ERR(ebufp);

    dummyp = pbo_decimal_from_str("0.0", ebufp);
    /***********************************************************
     * Set the balance impact type as pre-rated.
     ***********************************************************/
    impact_type = PIN_IMPACT_TYPE_PRERATED;

    bia_flistp = PIN_FLIST_CREATE(ebufp);

    /***********************************************************
     * Walk the PIN_FLD_TOTALS array in the original event and
     * add a corresponding balance impact arary for that.
     ***********************************************************/
    while ((flistp = PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_TOTAL,
                     &rec_id, 1, &cookie, ebufp)) != (pin_flist_t *)NULL) {

        /***************************************************
         * Add a new element for this balance impact.
         ***************************************************/
        count = (int)PIN_FLIST_ELEM_COUNT(bia_flistp,
                                          PIN_FLD_BAL_IMPACTS, ebufp);
        bi_flistp = PIN_FLIST_ELEM_ADD(bia_flistp,
                                       PIN_FLD_BAL_IMPACTS, count, ebufp);

        /***************************************************
         * Start filling in the standard field values now.
         ***************************************************/
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_IMPACT_TYPE,
                          (void *)&impact_type, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_RESOURCE_ID,
                          (void *)&rec_id, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_TAX_CODE,
                          (void *)"", ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_RATE_TAG,
                          (void *)"", ebufp);

        /***************************************************
         * Get and Set the account and item object poids.
         ***************************************************/
        vp = PIN_FLIST_FLD_GET(a_flistp,
                               PIN_FLD_ACCOUNT_OBJ, 0, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp,
                          PIN_FLD_ACCOUNT_OBJ, vp, ebufp);

        vp = PIN_FLIST_FLD_GET(a_flistp,
                               PIN_FLD_ITEM_OBJ, 1, ebufp);
        if (vp) {
            PIN_FLIST_FLD_SET(bi_flistp,
                              PIN_FLD_ITEM_OBJ, vp, ebufp);
        }

        /***************************************************
         * Fill in the dummy rate object poid.
         ***************************************************/
        r_pdp = PIN_POID_CREATE(0, "", 0, ebufp);
        PIN_FLIST_FLD_PUT(bi_flistp, PIN_FLD_RATE_OBJ,
                          (void *)r_pdp, ebufp);

        /***************************************************
         * set the 0 for quantity, discount and percentage
         ***************************************************/
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_DISCOUNT,
                          (void *)dummyp, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_PERCENT,
                          (void *)dummyp, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_QUANTITY,
                          (void *)dummyp, ebufp);

        /***************************************************
         * Set the amount deferred to 0.0
         ***************************************************/
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_AMOUNT_DEFERRED,
                          (void *)dummyp, ebufp);

        /***************************************************
         * Get the amount and set in the bal impact.
         ***************************************************/
        vp = PIN_FLIST_FLD_GET(flistp, PIN_FLD_AMOUNT, 0, ebufp);
        PIN_FLIST_FLD_SET(bi_flistp, PIN_FLD_AMOUNT, vp, ebufp);

    }

    PIN_FLIST_CONCAT(a_flistp, bia_flistp, ebufp);

    PIN_FLIST_DESTROY_EX(&bia_flistp, NULL);
    pbo_decimal_destroy(&dummyp);
    /***********************************************************
     * Error?
     ***********************************************************/
    if (PIN_ERR_IS_ERR(ebufp)) {
        PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
                         "fm_act_pol_add_event_bal_impacts error", ebufp);
    }

    return;
}
/************************************************************************
 * fm_cust_pol_valid_add_fail():
 *
 *   	Add a field validation failure element to the given flist
 *	using the info passed in. We assume the flist has N field
 *	failures on it already with element ids of 0 to (N-1) so
 *	we add a new element with an element id of N.
 *
 *	No error checking is done on the values passed in, but we
 *	do allow for some values to be optional according to the
 *	PCM_OP_CUST_POL_VALID_* return flist specs.
 *
 *	We return a pointer to the element we add to facilitate
 *	layering (by the caller) of the validation failures within
 *	substruct and array fields.
 *
 ************************************************************************/
pin_flist_t *
fm_cust_pol_valid_add_fail(
	pin_flist_t	*r_flistp,
	u_int		field,
	u_int		elemid,
	u_int		result,
	char		*descr,
	void		*val,
	pin_errbuf_t	*ebufp)
{
	pin_flist_t	*flistp = NULL;
	u_int		my_id = 0;
	u_int		type = 0;
	u_int		fail = 0;

	if (PIN_ERR_IS_ERR(ebufp))
		return(flistp);
	PIN_ERR_CLEAR_ERR(ebufp);
	
	/****************************************************************
	 * Create the field failure element.
	 ****************************************************************/
	my_id = PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_FIELD, ebufp); 
	flistp = PIN_FLIST_ELEM_ADD(r_flistp, PIN_FLD_FIELD, my_id, ebufp);

	/****************************************************************
	 * If this is the first time, mark the main result as _FAILED.
	 ****************************************************************/
	if (my_id == 0) {
		fail = PIN_CUST_VERIFY_FAILED;
		PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_RESULT,
			(void *)&fail, ebufp);
	}

	/****************************************************************
	 * The required fields.
	 ****************************************************************/
	/*
	** PIN_FLD_FIELD_NUM.
	*/
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_FIELD_NUM, (void *)&field, ebufp);

	/*
	** PIN_FLD_RESULT.
	*/
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp);

	/****************************************************************
	 * The optional fields.
	 ****************************************************************/
	/*
	** PIN_FLD_ELEMENT_ID
	*/
	if (elemid != (u_int)NULL) {
		PIN_FLIST_FLD_SET(flistp, PIN_FLD_ELEMENT_ID,
			(void *)&elemid, ebufp);
	}

	/*
	** PIN_FLD_DESCR.
	*/
	if (descr != (char *)NULL) {
		PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp);
	}

	/*
	** The actual field value.
	*/
	type = PIN_FIELD_GET_TYPE(field);
	switch (type) {
	case PIN_FLDT_ARRAY:
	case PIN_FLDT_SUBSTRUCT:
		break;
	default:
		/* Val reqd on list - even if NULL */
		PIN_FLIST_FLD_SET(flistp, field, (void *)val, ebufp);
	}

	/* Error? */
	if (PIN_ERR_IS_ERR(ebufp)) {
		PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
			"error", ebufp);
	}

	return(flistp);
}
void
fm_cust_pol_create_metafield_obj(
    pcm_context_t           *ctxp,
    int32                    flags,
    pin_flist_t             *in_flistp,
    pin_flist_t            **ret_flistpp,
    pin_errbuf_t            *ebufp)

{
    void 		   *vp = NULL;
    int 		   count =0;
    int64        database  = pcm_get_current_db_no(ctxp);
    pin_flist_t   *i_flist = NULL;
    pin_flist_t   *sub_flistp = NULL;
    pin_flist_t   *r_flistp = NULL;
    char 	      *program_name = NULL;
    char 	      *class_name= NULL;
    char 	      *default_value= NULL;
    int 	       fld_type=0;

    if(PIN_ERRBUF_IS_ERR(ebufp))
        return;
    PIN_ERR_CLEAR_ERR(ebufp);

    *ret_flistpp = NULL;

    //Count FIELDS array
    count = PIN_FLIST_ELEM_COUNT(in_flistp,PIN_FLD_VALUES,ebufp);


    if (count==0)
        return;

    if(count==1)
    {

        i_flist= PIN_FLIST_CREATE(ebufp);
        vp = PIN_FLIST_FLD_GET(in_flistp,PIN_FLD_POID,1,ebufp);
        PIN_FLIST_FLD_SET(i_flist,PIN_FLD_POID,(void*)vp,ebufp);

        sub_flistp = PIN_FLIST_ELEM_GET(in_flistp, PIN_FLD_VALUES,PIN_ELEMID_ANY, 1, ebufp);
        program_name = PIN_FLIST_FLD_GET(sub_flistp,PIN_FLD_NAME,1,ebufp);
        PIN_FLIST_FLD_SET(i_flist,PIN_FLD_NAME,program_name,ebufp);

        fld_type =*(int*) PIN_FLIST_FLD_GET(sub_flistp,PIN_FLD_TYPE,1,ebufp);
        PIN_FLIST_FLD_SET(i_flist,PIN_FLD_TYPE,&fld_type,ebufp);

        class_name=PIN_FLIST_FLD_GET(sub_flistp,PIN_FLD_CLASS_NAME,1,ebufp);
        PIN_FLIST_FLD_SET(i_flist,PIN_FLD_CLASS_NAME,class_name,ebufp);

        default_value=PIN_FLIST_FLD_GET(sub_flistp,PIN_FLD_DEFAULT_VALUE,1,ebufp);
        if(default_value)
            PIN_FLIST_FLD_SET(i_flist,PIN_FLD_DEFAULT_VALUE,default_value,ebufp);

        if (PIN_ERRBUF_IS_ERR(ebufp))
        {
            PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,"Error Occured while creating the input flist",ebufp);
            return;
        }

        PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,"input flist for metafield obj ",i_flist);


        //Call pcm_op_create_obj
        PCM_OP(ctxp,PCM_OP_CREATE_OBJ,0,i_flist,ret_flistpp,ebufp);

        if(PIN_ERRBUF_IS_ERR(ebufp))
        {
            PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,"Error Occured while calling PCM_OP_CREATE_OBJ",ebufp);
            return;
        }

    }
    else if (count >1)
    {
        //Call pcm_op_bulk_create_obj
        PCM_OP(ctxp,PCM_OP_BULK_CREATE_OBJ ,0,in_flistp,ret_flistpp,ebufp);

        if(PIN_ERRBUF_IS_ERR(ebufp))
        {
            PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,"Error Occured while calling PCM_OP_BULK_CREATE_OBJ" ,ebufp);
            return;
        }
    }

    if(ret_flistpp)
        PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,"Output flist for metafield obj ",*ret_flistpp);

    return;

}
static void
fm_get_meta_field(
	pcm_context_t           *ctxp,
        pin_flist_t             *in_flistp,
        pin_flist_t             **out_flistpp,
        pin_errbuf_t            *ebufp)
{
	pin_flist_t     *keys_flistp = NULL;
        pin_flist_t     *search_flistp = NULL;
        pin_flist_t     *flistp = NULL; 
        poid_t          *s_pdp = NULL; 
        poid_t          *bi_pdp = NULL; 
        int64           database = 0;
        int32           sflags = 256;
        int32           result = PIN_BOOLEAN_FALSE;
        void            *vp = NULL;
        pin_decimal_t   *zero_decimal =  pin_decimal("0.0", ebufp);
	pin_flist_t	*r_flistp = NULL;
	char                    *name = NULL;
	char                    *class_name = NULL;
	char                    *default_value;
	int32           count = 0;
	int32           cnt_flds = 0;
	int32                   elemid = 1;
	pin_errbuf_t            any_field_ebuf;
        pin_cookie_t            cookie = NULL;
        pin_fld_num_t           field = 0;
        int32                   rec_id = 0;
	void            *type = NULL;

        if (PIN_ERR_IS_ERR(ebufp)) {
                return;
        }
        PIN_ERR_CLEAR_ERR(ebufp);
	PIN_ERR_CLEAR_ERR(&any_field_ebuf);
	
	PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "fm_get_meta_field input flistp", in_flistp);
	bi_pdp = (poid_t *) PIN_FLIST_FLD_GET(in_flistp,
                                PIN_FLD_POID,0, ebufp);

	count = PIN_FLIST_ELEM_COUNT (in_flistp,
                        PIN_FLD_KEYS, ebufp);
	if (count == 0)
        {

                 pin_set_err(ebufp, PIN_ERRLOC_FM,
                        PIN_ERRCLASS_SYSTEM_DETERMINATE,
                        PIN_ERR_BAD_OPCODE, 0, 0, count);
                PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
                        "op_get_meta_field search flistp", ebufp);

                *out_flistpp = NULL;
                return;
        }

	else {
	keys_flistp = PIN_FLIST_ELEM_GET (in_flistp, PIN_FLD_KEYS,
                PIN_ELEMID_ANY, 0, ebufp);
	while (PIN_FLIST_ANY_GET_NEXT(keys_flistp, &field,
                                &rec_id, &cookie, &any_field_ebuf) != NULL ){
        cnt_flds = cnt_flds + 1;
	if (field == PIN_FLD_NAME){
 	name = (char *)PIN_FLIST_FLD_GET(keys_flistp, PIN_FLD_NAME, 1, ebufp);
	}
	if (field == PIN_FLD_CLASS_NAME){
       class_name = PIN_FLIST_FLD_GET(keys_flistp, PIN_FLD_CLASS_NAME, 0, ebufp );
	}
	if (field == PIN_FLD_TYPE){
	type = PIN_FLIST_FLD_GET(keys_flistp, PIN_FLD_TYPE, 0, ebufp );			
	}
	}
	if ( cnt_flds == 1)
        {
        vp = (void *)"select X from /metafield where F1 = V1 ";
        }
        if ( cnt_flds == 2)
        {
        vp = (void *)"select X from /metafield where F1 = V1 and F2 = V2 ";
        }
        if ( cnt_flds == 3)
        {
        vp = (void *)"select X from /metafield where F1 = V1 and F2 = V2 and F3 = V3 ";
        }

	 /*********************************************************
         * Create the search flist to search in the item objects
         *********************************************************/
        search_flistp = PIN_FLIST_CREATE(ebufp);
        database = PIN_POID_GET_DB(bi_pdp);
        s_pdp = PIN_POID_CREATE(database, "/search", -1, ebufp);
        PIN_FLIST_FLD_PUT(search_flistp, PIN_FLD_POID, (void *)s_pdp, ebufp);
       /******************************************************************
         * Set the search template.
         ******************************************************************/
        PIN_FLIST_FLD_SET(search_flistp, PIN_FLD_TEMPLATE, vp, ebufp);
        PIN_FLIST_FLD_SET(search_flistp, PIN_FLD_FLAGS, (void *)&sflags, ebufp);

	/*********************************************************
         * Add the search arguments.
         *********************************************************/
	if (name != NULL) {
        flistp = PIN_FLIST_ELEM_ADD(search_flistp, PIN_FLD_ARGS, elemid++, ebufp);
        PIN_FLIST_FLD_SET(flistp, PIN_FLD_NAME, name, ebufp);
	}

        /*********************************************************
         * Add the search arguments.
         *********************************************************/
	if (class_name != NULL) {
        flistp = PIN_FLIST_ELEM_ADD(search_flistp, PIN_FLD_ARGS, elemid++, ebufp);
        PIN_FLIST_FLD_SET(flistp, PIN_FLD_CLASS_NAME, class_name, ebufp);
        }
	
	/*********************************************************
         * Add the search arguments.
         *********************************************************/
        if (type != NULL) {
        flistp = PIN_FLIST_ELEM_ADD(search_flistp, PIN_FLD_ARGS, elemid++, ebufp);
        PIN_FLIST_FLD_SET(flistp, PIN_FLD_TYPE, type, ebufp);
        }


        /*********************************************************
         * Add the result array for the search.
         *********************************************************/

        flistp = PIN_FLIST_ELEM_ADD(search_flistp, PIN_FLD_RESULTS, 0, ebufp);
	PIN_FLIST_FLD_SET(flistp, PIN_FLD_TYPE,(void *)NULL, ebufp);
        
	PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "op_get_meta_field search flistp", search_flistp);  

	 PCM_OP(ctxp, PCM_OP_SEARCH, 0, search_flistp, out_flistpp, ebufp);

	PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "op_get_meta_field search flistp", *out_flistpp);
	}
	     
 	}
void
fm_cust_pol_valid_login_check_uniquiness_service(
	pcm_context_t		*ctxp,
	int64			db_no,
	int			msexchange_service_type,
	pin_flist_t		*i_flistp,
	pin_flist_t		*r_flistp,
	pin_errbuf_t		*ebufp)
{
	pin_flist_t		*a_flistp = NULL;
	pin_flist_t		*l_flistp = NULL;
	pin_flist_t		*n_flistp = NULL;
	pin_flist_t		*s1_flistp = NULL;
	pin_flist_t		*s2_flistp = NULL;
	pin_flist_t		*flistp = NULL;
	poid_t			*objp = NULL;
	poid_t			*s_pdp = NULL;
	void			*vp = NULL;
	const char		*subtype = NULL;
	char			*login = NULL;
	int32			result = PIN_CUST_VERIFY_PASSED;
	int32			elemid = 0;
	int32			count1 = 0;
	int32			count2 = 0;
	int32			search_flag = SRCH_DISTINCT;
	pin_cookie_t		cookie = NULL;
	pin_cookie_t		cookie2 = NULL;
	int			count = 0;
	int32			cred = 0;

        /***********************************************************
         * Return immediately if there's an error in ebufp.
         ***********************************************************/
        if (PIN_ERR_IS_ERR(ebufp))
                return;
        PIN_ERR_CLEAR_ERR(ebufp);

	s_pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_POID, 0, ebufp);
	/*********************************************************
	 * Create the search flist
	 ********************************************************/
	s1_flistp = PIN_FLIST_CREATE(ebufp);
	s2_flistp = PIN_FLIST_CREATE(ebufp);
	objp = PIN_POID_CREATE(db_no, "/search", -1, ebufp);
	PIN_FLIST_FLD_SET(s1_flistp, PIN_FLD_POID, (void *)objp, ebufp);
	PIN_FLIST_FLD_PUT(s2_flistp, PIN_FLD_POID, (void *)objp, ebufp);

	/******************************************************************
	 * Set the search template.
	 ******************************************************************/

	/**********************************************************************
	 * If Service type is /service/msexchange/user or 
	 * /service/msexchange/user/firstadmin
	 * search login name in both /service/msexchange/user and 
	 * /service/msexchange/user/firstadmin objects
	 **********************************************************************/
	if( msexchange_service_type != PIN_MSEXCHANGE_SERVICE_NONE ){
		vp = (void*)"select X from /service where "
				"F1 = V1 AND ( F2 = V2 OR  F3 = V3 ) ";
	}
	else {
		vp = (void*)"select X from /service where "
				" F1 = V1 AND F2 = V2 ";
	}

	PIN_FLIST_FLD_SET(s1_flistp, PIN_FLD_TEMPLATE, vp, ebufp);
	PIN_FLIST_FLD_SET(s2_flistp, PIN_FLD_TEMPLATE, vp, ebufp);
	PIN_FLIST_FLD_SET(s1_flistp, PIN_FLD_FLAGS, &search_flag, ebufp);
	PIN_FLIST_FLD_SET(s2_flistp, PIN_FLD_FLAGS, &search_flag, ebufp);

	/* Add the search criteria. */
	login = PIN_FLIST_FLD_GET( i_flistp, PIN_FLD_LOGIN, 1, ebufp );
	
	/* Look for PIN_FLD_LOG = login */
	l_flistp = PIN_FLIST_ELEM_ADD(s1_flistp, PIN_FLD_ARGS, 1, ebufp);
	PIN_FLIST_FLD_SET(l_flistp, PIN_FLD_LOGIN, (void *)login, ebufp);

	/* Look for PIN_FLD_ALIAS_LIST - PIN_FLD_NAME = login */
	n_flistp = PIN_FLIST_ELEM_ADD(s2_flistp, PIN_FLD_ARGS, 1, ebufp);
	n_flistp = PIN_FLIST_ELEM_ADD(n_flistp, PIN_FLD_ALIAS_LIST, 
					PIN_ELEMID_ANY, ebufp);
	PIN_FLIST_FLD_SET(n_flistp, PIN_FLD_NAME, (void *)login, ebufp);

	/**********************************************************************
	 * If service is /service/msexchange/user type, search login name also
	 * in /service/msexchange/user/firstadmin for unique login name and 
	 * vice versa.
	 * Add F3 and V3 Parameters in search template with service type
	 **********************************************************************/
	if( msexchange_service_type == PIN_MSEXCHANGE_SERVICE_USER ||
		msexchange_service_type == PIN_MSEXCHANGE_SERVICE_FIRSTADMIN ){
		a_flistp = PIN_FLIST_ELEM_ADD(s1_flistp, PIN_FLD_ARGS,2, ebufp);
		objp = PIN_POID_CREATE(db_no, 
			PIN_MSEXCHANGE_SERVICE_TYPE_FIRSTADMIN,
	       		(int64)-1, ebufp);
		PIN_FLIST_FLD_PUT(a_flistp, PIN_FLD_POID, (void *)objp, ebufp);
		PIN_FLIST_ELEM_SET(s2_flistp, a_flistp, PIN_FLD_ARGS, 2, ebufp);

		a_flistp = PIN_FLIST_ELEM_ADD(s1_flistp, PIN_FLD_ARGS,3, ebufp);
		objp = PIN_POID_CREATE(db_no, PIN_MSEXCHANGE_SERVICE_TYPE_USER,
	       		(int64)-1, ebufp);
		PIN_FLIST_FLD_PUT(a_flistp, PIN_FLD_POID, (void *)objp, ebufp);
		PIN_FLIST_ELEM_SET(s2_flistp, a_flistp, PIN_FLD_ARGS, 3, ebufp);
	} else {
		subtype = PIN_POID_GET_TYPE( s_pdp );
		a_flistp = PIN_FLIST_ELEM_ADD(s1_flistp, PIN_FLD_ARGS,2, ebufp);
		objp = PIN_POID_CREATE(db_no, subtype, (int64)-1, ebufp);
		PIN_FLIST_FLD_PUT(a_flistp, PIN_FLD_POID, (void *)objp, ebufp);
		PIN_FLIST_ELEM_SET(s2_flistp, a_flistp, PIN_FLD_ARGS, 2, ebufp);
	}

	PIN_FLIST_ELEM_PUT(s1_flistp, NULL, PIN_FLD_RESULTS, 0, ebufp);
	PIN_FLIST_ELEM_PUT(s2_flistp, NULL, PIN_FLD_RESULTS, 0, ebufp);

	/************************************************************
	 * we only search if there was a login
	 * otherwise this was all setup for the alias list searches.
	 ************************************************************/
	if( login ) {
		cred = CM_FM_BEGIN_OVERRIDE_SCOPE(CM_CRED_SCOPE_OVERRIDE_ROOT);
		PCM_OP(ctxp, PCM_OP_SEARCH, PCM_OPFLG_COUNT_ONLY,
			s1_flistp, &a_flistp, ebufp);

		cookie = NULL;
		(void) PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_RESULTS, 
			&count1, 0, &cookie, ebufp);	
		PIN_FLIST_DESTROY_EX( &a_flistp, NULL );

		PCM_OP(ctxp, PCM_OP_SEARCH, PCM_OPFLG_COUNT_ONLY,
			s2_flistp, &a_flistp, ebufp);
		CM_FM_END_OVERRIDE_SCOPE(cred);

		cookie = NULL;
		(void) PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_RESULTS, 
			&count2, 0, &cookie, ebufp);	
		PIN_FLIST_DESTROY_EX( &a_flistp, NULL );

		if (count1 > 0 || count2 > 0 ) {
			(void)fm_cust_pol_valid_add_fail(r_flistp, 
				PIN_FLD_LOGIN, (u_int)NULL,
				PIN_CUST_VAL_ERR_DUPE,
				PIN_CUST_DUPE_VALUE_ERR_MSG, 
				(void *)login, ebufp);
               		result = PIN_CUST_VERIFY_FAILED;
		}
	}

	/***********************************************************
         * Try to validate all of the alias list
         ***********************************************************/
	cookie = NULL;
	for ( 
		flistp = PIN_FLIST_ELEM_GET_NEXT( i_flistp, PIN_FLD_ALIAS_LIST,
						&elemid, 0, &cookie, ebufp );
		ebufp->pin_err == PIN_ERR_NONE;
		flistp = PIN_FLIST_ELEM_GET_NEXT( i_flistp, PIN_FLD_ALIAS_LIST,
						&elemid, 0, &cookie, ebufp )
	) {

		if ( !flistp ) continue;

		login = PIN_FLIST_FLD_GET( flistp, PIN_FLD_NAME, 0, ebufp );
	
		/**************************************************************
		 * the search flist is still set up we just need to replace
		 * the login value with an alias value.
		 **************************************************************/
		PIN_FLIST_FLD_SET(l_flistp, PIN_FLD_LOGIN, (void *)login, ebufp);
		PIN_FLIST_FLD_SET(n_flistp, PIN_FLD_NAME, (void *)login, ebufp);

		cred = CM_FM_BEGIN_OVERRIDE_SCOPE(CM_CRED_SCOPE_OVERRIDE_ROOT);
		PCM_OP(ctxp, PCM_OP_SEARCH, PCM_OPFLG_COUNT_ONLY,
			s1_flistp, &a_flistp, ebufp);

		cookie2 = NULL;
		(void) PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_RESULTS, 
			&count1, 0, &cookie2, ebufp);	

		PIN_FLIST_DESTROY_EX( &a_flistp, NULL );

		PCM_OP(ctxp, PCM_OP_SEARCH, PCM_OPFLG_COUNT_ONLY,
			s2_flistp, &a_flistp, ebufp);
		CM_FM_END_OVERRIDE_SCOPE(cred);

		cookie2 = NULL;
		(void) PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_RESULTS, 
			&count2, 0, &cookie2, ebufp);	

		PIN_FLIST_DESTROY_EX( &a_flistp, NULL );

		if (count1 > 0 || count2 > 0) {
			pin_fld_num_t field = PIN_FLD_ALIAS_LIST;
			/***************************************************
			 * There is a validation error so normalize it to
			 * the input flist
			 ***************************************************/
			result = PIN_CUST_VERIFY_FAILED;
			count = PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_FIELD, 
					ebufp);
			a_flistp = PIN_FLIST_ELEM_ADD(r_flistp, PIN_FLD_FIELD,
					count, ebufp);
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_FIELD_NUM,
					(void *)&field, ebufp);
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_ELEMENT_ID,
					(void *)&elemid, ebufp);
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_RESULT,
					(void *)&result, ebufp);
			(void)fm_cust_pol_valid_add_fail(a_flistp, 
				PIN_FLD_NAME, (u_int)NULL,
				PIN_CUST_VAL_ERR_DUPE,
				PIN_CUST_DUPE_VALUE_ERR_MSG, 
				(void *)login, ebufp);
			a_flistp = NULL;
		}
	}
	if ( ebufp->pin_err == PIN_ERR_NOT_FOUND ) {
		PIN_ERR_CLEAR_ERR( ebufp );
	}


	if ( result == PIN_CUST_VERIFY_FAILED ) {
		PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_RESULT,
				(void *)&result, ebufp);
	}
	PIN_FLIST_DESTROY_EX( &s1_flistp, NULL );
	PIN_FLIST_DESTROY_EX( &s2_flistp, NULL );
	
}
/*******************************************************************
 * fm_cust_pol_valid_login()
 *
 *	Validate the given login according to the given poid type.
 *
 *	For now, logins are required (ie they can't be NULL) and
 *	must be less than the maximum length (currently 255).
 *
 *******************************************************************/
static void
fm_cust_pol_valid_login(cm_nap_connection_t	*connp,
			pin_flist_t		*i_flistp,
			int32			flags,
			pin_flist_t		**o_flistpp,
			pin_errbuf_t		*ebufp)
{
	pin_cookie_t		cookie = NULL;
	pin_flist_t		*r_flistp = NULL;
	pin_flist_t		*s_flistp = NULL;
	pin_flist_t		*a_flistp = NULL;
	pin_flist_t		*flistp = NULL;
	poid_t			*o_pdp = NULL;
	char			*login = NULL;
	void                    *vp = NULL;
	pcm_context_t		*ctxp = connp->dm_ctx;
	
	const char		*subtype = NULL;
	int32			result = PIN_CUST_VERIFY_PASSED;
	int32			elemid;
	int64			db_no;
	int			count = 0;
	int 			msexchange_service_type = 
	                                  PIN_MSEXCHANGE_SERVICE_NONE;



	/***********************************************************
         * Return immediately if there's an error in ebufp.
         ***********************************************************/
	if (PIN_ERR_IS_ERR(ebufp))
		return;
	PIN_ERR_CLEAR_ERR(ebufp);

	/***********************************************************
	 * Create outgoing flist
	 ***********************************************************/
	r_flistp = PIN_FLIST_CREATE(ebufp);
	*o_flistpp = r_flistp;

	/***********************************************************
	 * Get (and add) the object poid.
	 ***********************************************************/
	o_pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_POID, 0, ebufp);
	PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_POID, (void *)o_pdp, ebufp);


	/***********************************************************
	 * Get the input login.
	 ***********************************************************/
	login = (char *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_LOGIN, 1, ebufp);
	
	/* 
	 *  LOGIN could be NULL if SET_LOGIN is called to set an alias entry
	 *  during SERVICE creation
	 */
	if (login != NULL) {
		count =  PIN_FLIST_ELEM_COUNT(i_flistp, PIN_FLD_ALIAS_LIST, 
					      ebufp);
		/***************************************************
		 * Try to validate based on /config/fld_validate 
		 * (Login) obj, if it is a new service with alias
		 * list or modifying a login with no alias list
		 **************************************************/
		if ((count < 1) || (fm_utils_op_is_ancestor(
			connp->coip, PCM_OP_CUST_CREATE_SERVICE))) {
			fm_cust_pol_validate_fld_value( ctxp, i_flistp, 
							i_flistp, r_flistp, 
							PIN_FLD_LOGIN, 
							0, "Login", 1, ebufp);
		}
	}

	/***********************************************************
         * Try to validate all of the alias list
         ***********************************************************/
	a_flistp = NULL;
	for ( 
		flistp = PIN_FLIST_ELEM_GET_NEXT( i_flistp, PIN_FLD_ALIAS_LIST,
						&elemid, 0, &cookie, ebufp );
		ebufp->pin_err == PIN_ERR_NONE;
		flistp = PIN_FLIST_ELEM_GET_NEXT( i_flistp, PIN_FLD_ALIAS_LIST,
						&elemid, 0, &cookie, ebufp )
	) {
		/***********************************************************
      	 	 * Prep the return flist
       		 ***********************************************************/
		if ( !a_flistp ) {
			a_flistp = PIN_FLIST_CREATE(ebufp);
		}

		if ( !flistp ) continue;

		/***********************************************************
      	 	 * Try to validate based on /config/fld_validate 
		 * (name) obj.  but since we cannot validate a value in
		 * PIN_FLD_NAME due to the facte we have to pass PIN_FLD_NAME
		 * as the name of the validation rule.  I will cady the 
		 * the PIN_FLD_NAME in a PIN_FLD_LOGIN and then manipulate 
		 * the error output if there is one.
       		 ***********************************************************/
		vp = PIN_FLIST_FLD_GET( flistp, PIN_FLD_NAME, 0, ebufp );
		PIN_FLIST_FLD_SET( flistp, PIN_FLD_LOGIN, vp, ebufp );
		fm_cust_pol_validate_fld_value( ctxp, i_flistp, flistp, 
			a_flistp, PIN_FLD_LOGIN, 0, "Login", 1, ebufp);
		PIN_FLIST_FLD_DROP( flistp, PIN_FLD_LOGIN, ebufp );

		if (PIN_FLIST_ELEM_COUNT(a_flistp, PIN_FLD_FIELD, ebufp) != 0) {
			/***************************************************
			 * There is a validation error so normalize it to
			 * the input flist
			 ***************************************************/
			pin_fld_num_t field = PIN_FLD_ALIAS_LIST;
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_FIELD_NUM,
					(void *)&field, ebufp);
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_ELEMENT_ID,
					(void *)&elemid, ebufp);
			result = PIN_CUST_VERIFY_FAILED;
			PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_RESULT,
					(void *)&result, ebufp);
			count = PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_FIELD, 
					ebufp);
			PIN_FLIST_ELEM_PUT(r_flistp, a_flistp, PIN_FLD_FIELD,
					count, ebufp);
			a_flistp = PIN_FLIST_ELEM_GET( a_flistp, PIN_FLD_FIELD, 
					PIN_ELEMID_ANY, 0, ebufp );
			field = PIN_FLD_NAME;
			PIN_FLIST_FLD_SET( a_flistp, PIN_FLD_FIELD_NUM, 
					(void *)&field, ebufp );
			a_flistp = NULL;
		}

	}
	if ( ebufp->pin_err == PIN_ERR_NOT_FOUND ) {
		PIN_ERR_CLEAR_ERR( ebufp );
	}

	/***************************************************************
	 * clean up any last unused a_flistp
	 ***************************************************************/
	PIN_FLIST_DESTROY_EX( &a_flistp, NULL );

	if (PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_FIELD, ebufp) != 0) {
               	result = PIN_CUST_VERIFY_FAILED;
		goto Done;
	}
	
	/***************************************************************
	 * Get the poid type to check service type. Used for E2K service
	 ***************************************************************/
	db_no = PIN_POID_GET_DB(o_pdp);
	subtype = PIN_POID_GET_TYPE(o_pdp);
	if ( subtype && 
		(strcmp(subtype, PIN_MSEXCHANGE_SERVICE_TYPE_USER) == 0)){
		msexchange_service_type = PIN_MSEXCHANGE_SERVICE_USER;
	}
	if ( subtype && 
		(strcmp(subtype, PIN_MSEXCHANGE_SERVICE_TYPE_FIRSTADMIN) == 0)){
		msexchange_service_type = PIN_MSEXCHANGE_SERVICE_FIRSTADMIN;
	}

	/***********************************************************
	 * Reject login change for /service/gsm type and subtype
	 ***********************************************************/
	if (subtype &&
		(!(strncmp(subtype, "/service/gsm", 12)))) {
		/***************************************************
		 * if user try to change the login and it's not allowed
		 ***************************************************/
		char * login = NULL;
		login = (char *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_LOGIN,
			1, ebufp);
		if (login == NULL) {
			goto Done;
		} else {
			if (!(fm_utils_op_is_ancestor(connp->coip,
				PCM_OP_CUST_COMMIT_CUSTOMER))&&
			!(fm_utils_op_is_ancestor(connp->coip,
				PCM_OP_CUST_MODIFY_CUSTOMER))&&
			!(flags & PCM_OPFLG_CUST_REGISTRATION)) {
				(void)fm_cust_pol_valid_add_fail(r_flistp,
				PIN_FLD_LOGIN, (u_int)NULL,
				PIN_CUST_VAL_ERR_REJECT,
				PIN_CUST_REJECT_VALUE_ERR_MSG,
				(void *)login, ebufp);
				result = PIN_CUST_VERIFY_FAILED;
				goto Done;
			} 
		}
	}

	/***********************************************************
	* Reject login change for /service/telco type and subtype
	***********************************************************/
        if (subtype &&
            ((!(strncmp(subtype, "/service/telco/", 15))) ||
                (!(strcmp(subtype, "/service/telco"))))) {
                /***************************************************
                 * if user try to change the login and it's not allowed
                 ***************************************************/
                char * login = NULL;
                login = (char *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_LOGIN,
                                                  1, ebufp);
		if (login == NULL) {
			goto Done;
		} else {
			if (!(fm_utils_op_is_ancestor(connp->coip,
					     PCM_OP_CUST_COMMIT_CUSTOMER))&&
			!(fm_utils_op_is_ancestor(connp->coip,
					     PCM_OP_CUST_MODIFY_CUSTOMER))&&
			!(flags & PCM_OPFLG_CUST_REGISTRATION)) {
				(void)fm_cust_pol_valid_add_fail(r_flistp,
				PIN_FLD_LOGIN, (u_int)NULL,
				PIN_CUST_VAL_ERR_REJECT,
				PIN_CUST_REJECT_VALUE_ERR_MSG,
				(void *)login, ebufp);
				result = PIN_CUST_VERIFY_FAILED;
				goto Done;
			}
                }
        }
	/***********************************************************
	 * If we're still ok, check uniqueness, in case of multi_db 
	 * and single-schema TT env.
	 * In case of multi-db approach and  single-schema TT env, we 
	 * need to check in the uniqueness table, otherwise proceed 
	 * as before.
	 * We need to use both the service type and the login.
         ***********************************************************/
	if (cm_fm_is_multi_db() || cm_fm_is_timesten()) {

		int64		primary_db_no = 0;
		int64		trans_db_no = 0;
		pcm_context_t	*vctxp = NULL;
		poid_t		*trans_poidp = NULL;
		pin_flist_t	*trans_flistp = NULL;

		/***************************************************
 	 	 * Put in all the fields we need to insert the
 	 	 *  entry into the uniqueness table
 	 	 ***************************************************/
		cm_fm_get_primary_db_no(&primary_db_no, ebufp);

                trans_flistp = pcm_get_trans_flist(ctxp);
                if ( trans_flistp ) {
			trans_poidp = PIN_FLIST_FLD_GET(trans_flistp, 
							PIN_FLD_POID, 0, ebufp);
			trans_db_no = PIN_POID_GET_DB( trans_poidp );
                } else {
			trans_db_no = primary_db_no;
		}
		PIN_FLIST_DESTROY_EX( &trans_flistp, NULL );

		/* 
		 *if we are looking at a different db then we currently have a 
		 * transaction in then we need a new context 
		 */
		if ( primary_db_no != trans_db_no ) {
			PCM_CONTEXT_OPEN(&vctxp, (pin_flist_t *)0, ebufp);
		} else {
			vctxp = ctxp;
		}

		fm_cust_pol_valid_login_check_uniquiness_table( vctxp,
        				primary_db_no, 
					msexchange_service_type, 
					i_flistp, r_flistp, ebufp );

		if ( primary_db_no != trans_db_no ) {
			PCM_CONTEXT_CLOSE(vctxp, 0, NULL);
		}

		
	} else {

		/*********************************************************
		 * This happens only for a single db installation
		 * where we don't have to search in the uniqueness table.
		 ********************************************************/

		fm_cust_pol_valid_login_check_uniquiness_service( ctxp,
					db_no, msexchange_service_type, 
					i_flistp, r_flistp, ebufp );
	}

	if (PIN_FLIST_ELEM_COUNT(r_flistp, PIN_FLD_FIELD, ebufp) != 0) {
               	result = PIN_CUST_VERIFY_FAILED;
		goto Done;
	}

Done:
	PIN_FLIST_DESTROY_EX(&s_flistp, NULL);
	PIN_FLIST_DESTROY_EX(&a_flistp, NULL);
	/***********************************************************
         * Set the overall result and return.
         ***********************************************************/
        PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_RESULT, (void *)&result, ebufp);

	/***********************************************************
	 * Error?
	 ***********************************************************/
	if (PIN_ERR_IS_ERR(ebufp)) {
		PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
			"fm_cust_pol_valid_login error", ebufp);
	}
	return;
}
static void 
fm_bill_pol_prepare_pending_items(
	pcm_context_t		*ctxp,
	pin_flist_t		*i_flistp, 
	pin_flist_t		**r_flistpp,
	pin_errbuf_t		*ebufp)
{
	pin_flist_t     *s_flistp = NULL;
	pin_flist_t     *o_flistp = NULL;
	pin_flist_t     *temp_flistp = NULL;
	pin_cookie_t    cookie = NULL;
	int32           rec_id = 0;
	int32           rec_id1 = 0;
	void            *vp = NULL;
	int64           database = 0;
	int32           count = 0;
	int32		*status = NULL;

	if (PIN_ERR_IS_ERR(ebufp))
                return;
        PIN_ERR_CLEAR_ERR(ebufp);

	*r_flistpp = PIN_FLIST_CREATE(ebufp);

	count = PIN_FLIST_ELEM_COUNT(i_flistp, PIN_FLD_ITEMS, ebufp);
	if (count == 1) {
		temp_flistp = PIN_FLIST_ELEM_GET_NEXT(i_flistp, PIN_FLD_ITEMS,
				&rec_id, 1, &cookie, ebufp);
		vp = PIN_FLIST_FLD_GET(temp_flistp, PIN_FLD_ITEM_OBJ, 1, ebufp);
		if (PIN_POID_IS_NULL((poid_t *)vp)) {
                	goto cleanup;	
		}
	}

	s_flistp = PIN_FLIST_CREATE(ebufp);
       	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_ITEM_TOTAL, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_ADJUSTED, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_DISPUTED, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_WRITEOFF, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_RECVD, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_TRANSFERED, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_SERVICE_OBJ, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_BILL_OBJ, NULL, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_STATUS, NULL, ebufp);

	cookie = NULL;
	while ((temp_flistp = PIN_FLIST_ELEM_GET_NEXT(i_flistp, PIN_FLD_ITEMS,
				&rec_id, 1, &cookie, ebufp))) {

		vp = PIN_FLIST_FLD_GET(temp_flistp, PIN_FLD_ITEM_OBJ, 1, ebufp);
		if (PIN_POID_IS_NULL((poid_t *)vp)) {
			pin_set_err(ebufp, PIN_ERRLOC_FM, 
			PIN_ERRCLASS_SYSTEM_DETERMINATE,
			PIN_ERR_BAD_VALUE, 0, 0, 0);
			PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
			"fm_bill_pol_prepare_pending_items error:"
			" Item Poid is NULL", ebufp);
                	goto cleanup;	
		}

        	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_POID, vp, ebufp);
        	PCM_OP(ctxp, PCM_OP_READ_FLDS, 0, s_flistp, &o_flistp, ebufp);
	        	
		/***********************************************************
		 * If the item status is pending add it to the results .
		 * Otherwise return.
		 **********************************************************/
		status = (int32 *)PIN_FLIST_FLD_GET(o_flistp, PIN_FLD_STATUS, 1,
									ebufp);
		if ((!status) || (*status != PIN_ITEM_STATUS_PENDING)) {
                       vp = PIN_FLIST_FLD_GET(o_flistp, PIN_FLD_BILL_OBJ, 1, 
                                                                        ebufp);
                        if (!status || PIN_POID_IS_NULL((poid_t *)vp)){
			        pin_set_err(ebufp, PIN_ERRLOC_FM, 
			        PIN_ERRCLASS_SYSTEM_DETERMINATE,
			        PIN_ERR_BAD_VALUE, 0, 0, 0);
			        PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
			        "fm_bill_pol_prepare_pending_items error:"
			        "Item Status is not pending", ebufp);
                	        goto cleanup;	
                        }
                       PIN_FLIST_DESTROY_EX(&o_flistp, NULL); 
                         continue;
                      
		}
		PIN_FLIST_FLD_DROP(o_flistp, PIN_FLD_STATUS, ebufp);

		PIN_FLIST_ELEM_PUT (*r_flistpp, o_flistp, PIN_FLD_RESULTS, 
							rec_id1++, ebufp);
		o_flistp = NULL;
	}

cleanup:

	if (PIN_ERR_IS_ERR(ebufp)) {
		PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
                        "fm_bill_pol_prepare_pending_items error ", ebufp);
		PIN_FLIST_DESTROY_EX(r_flistpp, NULL);
	}
	PIN_FLIST_DESTROY_EX(&s_flistp, NULL);
	PIN_FLIST_DESTROY_EX(&o_flistp, NULL);
	return;
}
/*******************************************************************
 * This function gets pending items to be included in the Bill.
 *******************************************************************/
static void 
fm_bill_pol_get_pending_items(
	pcm_context_t		*ctxp,
	pin_flist_t		*i_flistp, 
	pin_flist_t		**r_flistpp,
	pin_errbuf_t		*ebufp)
{
	pin_flist_t	*s_flistp = NULL;
	pin_flist_t	*temp_flistp = NULL;
	pin_flist_t	*o_flistp = NULL;
	pin_cookie_t	cookie = NULL;
	poid_t		*s_pdp = NULL;
	poid_t		*bi_pdp = NULL;
	poid_t		*acc_pdp = NULL;
	poid_t		*srv_pdp = NULL;
	poid_t		*srv_pdp1 = NULL;
	int32		rec_id = 0;
	int32		s_flags = 0;
	void		*vp = NULL;
	int64		database = 0;
	int32		status = 0;
	int		srv_cnt = 0;
	int		first_srv_flag = 0;
	char		s_template[BUFSIZ] = {0};
	char		tmp_s_template[BUFSIZ] = {0};

	if (PIN_ERR_IS_ERR(ebufp))
		return;
	PIN_ERR_CLEAR_ERR(ebufp);

	/**************************************************************
	 * Check whether the input flist contains the list of pendning
	 * items. If so, prepare output flist for the policy, and return
	 **************************************************************/
	if (PIN_FLIST_ELEM_GET_NEXT(i_flistp, PIN_FLD_ITEMS,
						&rec_id, 1, &cookie, ebufp)) {
		fm_bill_pol_prepare_pending_items(ctxp, i_flistp, r_flistpp,
							ebufp);
		return;
	}

	/*********************************************************
	 * Get billinfo poid
	 *********************************************************/
	bi_pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_BILLINFO_OBJ, 0,
									ebufp);
	/*********************************************************
	 * Get account poid
	 *********************************************************/
	acc_pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_POID, 0,
								  ebufp);
	/*********************************************************
	 * Create the search flist to search for the item objects
	 *********************************************************/
	s_flistp = PIN_FLIST_CREATE(ebufp);

	database = pin_poid_get_db(bi_pdp);
	s_pdp = (poid_t *)PIN_POID_CREATE(database, "/search", -1, ebufp);
	PIN_FLIST_FLD_PUT(s_flistp, PIN_FLD_POID, (void *)s_pdp, ebufp);
	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_FLAGS, (void *)&s_flags, ebufp);

        /***********************************************************
         * Start with the base search template. Add the search for list of
	 * services if they are presented in the input flist.
         ***********************************************************/
        strcpy(s_template, "select X from /item where F1 = V1 and F2 = V2 ");

	srv_pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, 
						PIN_FLD_SERVICE_OBJ, 1, ebufp);
	if (srv_pdp) {
		/***********************************************
		 * Get all services from the service group
		 ***********************************************/
		fm_utils_bill_get_service_group(ctxp, srv_pdp,acc_pdp,&o_flistp,
									ebufp);
		/***********************************************************
		 * Different 'where' clauses will be used depending on 
		 * whether the services array contains a single service or 
		 * multiple ones.
		 ***********************************************************/
		srv_cnt = PIN_FLIST_ELEM_COUNT(o_flistp, PIN_FLD_SERVICES, 
									ebufp);

		if (1 == srv_cnt) {
			strncpy(tmp_s_template, s_template,
				sizeof(tmp_s_template)-1);
			pin_snprintf(s_template, sizeof(s_template), "%s %s",
				tmp_s_template, "and F3 = V3");
			cookie = NULL;
			temp_flistp = PIN_FLIST_ELEM_GET_NEXT(o_flistp, 
						PIN_FLD_SERVICES, &rec_id, 0, 
						&cookie, ebufp);
			srv_pdp1 = (poid_t *)PIN_FLIST_FLD_GET(temp_flistp, 
						PIN_FLD_SERVICE_OBJ, 0, ebufp);
			/* Add ARG 3 - SERVICE_OBJ */
			temp_flistp = PIN_FLIST_ELEM_ADD(s_flistp,PIN_FLD_ARGS,
								3, ebufp);
			PIN_FLIST_FLD_SET(temp_flistp,
				PIN_FLD_SERVICE_OBJ, (void *)srv_pdp1, ebufp);
		} else { /* Multiple services */

			/******************************************************
			 * SEARCH CONDITION:  service_obj_id0 in 
			 * (poid_id_1, poid_id_2, ...  poid_id_n)
			 *****************************************************/

			/******************************************************
			 * Append the initial part of 'in' clause to search 
			 * template 
			 *****************************************************/
			strncpy(tmp_s_template, s_template,
				sizeof(tmp_s_template)-1);	
			pin_snprintf(s_template, sizeof(s_template), "%s %s",
				tmp_s_template, "and service_obj_id0 in (");

			cookie = NULL;
			while ((temp_flistp = PIN_FLIST_ELEM_GET_NEXT(o_flistp,
				PIN_FLD_SERVICES, &rec_id, 1, &cookie, ebufp))) {

				vp = (poid_t *)PIN_FLIST_FLD_GET(temp_flistp, 
						PIN_FLD_SERVICE_OBJ, 0, ebufp);

				if (first_srv_flag == 0) { /* First iteration */
					/*************************************
					 * NOTE: NO 'comma' before first poid ID
					 * in 'in' clause 
					 *************************************/
					first_srv_flag = 1;
				}
				else { /* NOT the first iteration */
					/*************************************
					 * Add 'comma' before adding this poid 
					 * ID to 'in' clause 
					 ************************************/
					strncpy(tmp_s_template, s_template,
						sizeof(tmp_s_template)-1);
					pin_snprintf(s_template, sizeof(s_template),
						"%s%s", tmp_s_template, ", ");
				}

				/* Add this poid ID to 'in' clause */
				strncpy(tmp_s_template, s_template,
					sizeof(tmp_s_template)-1);
				pin_snprintf(s_template, sizeof(s_template), 
					"%s%" I64_PRINTF_PATTERN "d",
					tmp_s_template, 
					PIN_POID_GET_ID((poid_t *)vp));
				}

			/*************************************
                	 * Append the last part of 'in' clause 
			 * to search template 
			 ************************************/
               		strncpy(tmp_s_template, s_template,
				sizeof(tmp_s_template)-1); 
			pin_snprintf(s_template, sizeof(s_template), "%s%s",
				tmp_s_template, ")");

        	} /* end else (multiple services) */
	}

	PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_TEMPLATE, (void *)s_template, 
									ebufp);
	/*********************************************************
	 * Add the search arguments. This is a 2 arg =, = search
	 *********************************************************/
	temp_flistp = PIN_FLIST_ELEM_ADD(s_flistp, PIN_FLD_ARGS, 1, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_BILLINFO_OBJ, (void *)bi_pdp,
			ebufp);

	status = PIN_ITEM_STATUS_PENDING;
	temp_flistp = PIN_FLIST_ELEM_ADD(s_flistp, PIN_FLD_ARGS, 2, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_STATUS, (void *)&status, ebufp);

	/*********************************************************
	 * Add the results array for the search.
	 *********************************************************/
	temp_flistp = PIN_FLIST_ELEM_ADD(s_flistp, PIN_FLD_RESULTS, 0, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_POID, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_ITEM_TOTAL, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_ADJUSTED, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_DISPUTED, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_WRITEOFF, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_RECVD, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_TRANSFERED, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_SERVICE_OBJ, NULL, ebufp);
	PIN_FLIST_FLD_SET(temp_flistp, PIN_FLD_BILL_OBJ, NULL, ebufp);

	/**********************************************************
	 * do real search
	 **********************************************************/
	PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,
                       "fm_bill_pol_get_pending_items search flist", s_flistp);
	PCM_OP(ctxp, PCM_OP_SEARCH, 0, s_flistp, r_flistpp, ebufp);


	PIN_FLIST_DESTROY_EX(&s_flistp, NULL);
	PIN_FLIST_DESTROY_EX(&o_flistp, NULL);

	/********************************************************* 
	 * Errors..?
	 *********************************************************/
	if (PIN_ERR_IS_ERR(ebufp)) {
		PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,
			"fm_bill_pol_get_pending_items error",ebufp);
	}
	return;
}