/******************************************************************* * Configuration * * Reads the pin.conf file to determine the database we want. * * Not actually needed here since we use PCM_CONNECT to * open our database connection and get the database # * returned as a by product. But this does illustrate * how to use pin_conf to retrieve conf'ed info. * *******************************************************************/ void sample_read_pin_conf( u_int64 *databasep, pin_errbuf_t *ebufp) { poid_t *db_pdp; int32 err; /*********************************************************** * Clear the error buffer. ***********************************************************/ PIN_ERR_CLEAR_ERR(ebufp); /*********************************************************** * Get the config userid to determine DB. * * Note: This allocates a poid that we must free. ***********************************************************/ pin_conf("-", "userid", PIN_FLDT_POID, (caddr_t *)&(db_pdp), &err); if (err != PIN_ERR_NONE) { ebufp->pin_err = err; return; } *databasep = PIN_POID_GET_DB(db_pdp); PIN_POID_DESTROY(db_pdp, NULL); return; }
/******************************************************************* * fm_bill_pol_spec_billno() * * Prep the billno for the given bill obj. * *******************************************************************/ static void fm_bill_pol_spec_billno( pcm_context_t *ctxp, u_int flags, pin_flist_t *in_flistp, pin_flist_t **out_flistpp, pin_errbuf_t *ebufp) { pin_flist_t *b_flistp = NULL; poid_t *pdp = NULL; void *vp = NULL; int64 poid_db; int64 poid_id; char billno[60]; if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); b_flistp = PIN_FLIST_COPY(in_flistp, ebufp); /*********************************************************** * We don't need a bill_no if the bill type is subordinate. ***********************************************************/ vp = PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_PAY_TYPE, 0, ebufp); if (vp != (void *)NULL) { PIN_FLIST_FLD_DROP(b_flistp, PIN_FLD_PAY_TYPE, ebufp); } /*********************************************************** * Set the BILL_NO field according to poid. ***********************************************************/ vp = PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_BILL_NO, 1, ebufp); if ((vp == (void *)NULL) || (strlen((char *)vp) <= 0)) { pdp = (poid_t *)PIN_FLIST_FLD_GET(in_flistp, PIN_FLD_POID, 0, ebufp); poid_db = PIN_POID_GET_DB(pdp); poid_id = PIN_POID_GET_ID(pdp); sprintf(billno, "%u.%u.%u.%u-%llu", (u_int)((poid_db & (u_int64)MASKUPPER) >> 48), (u_int)((poid_db & (u_int64)MASKSECOND) >> 32), (u_int)((poid_db & (u_int64)MASKTHIRD) >> 16), (u_int)(poid_db & (u_int64)0xFFFF), poid_id); PIN_FLIST_FLD_SET(b_flistp, PIN_FLD_BILL_NO, (void *)billno, ebufp); }
/* * Search for a brand name in the whole system. */ static void fm_cust_pol_is_brandname_unique_global( pcm_context_t *ctxp, poid_t *poidp, char *namep, pin_flist_t **r_flistpp, pin_errbuf_t *ebufp) { pin_flist_t *flistp = (pin_flist_t *)NULL; pin_flist_t *rlistp = (pin_flist_t *)NULL; pin_flist_t *sublistp; poid_t *search_poidp; int32 int_val; int32 cred; pin_account_type_t brand_type = PIN_ACCOUNT_TYPE_BRAND; pin_cookie_t cookie = (pin_cookie_t)NULL; /* * If there are pending errors, then short circuit immediately */ if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); /* * Create search flist to try to figure out if someone brand already * has this name. * * NOTE: we really only need to search for accounts that are of type * 'brand' and of a particular name. Unfortunately, neither of these * fields are indexed by default, thus causing a performance problem. * * To get around this, we'll turn this into a complex search. We know * that brands are the parent of a /group/billing object, so glue that * in as well. That should be indexed... */ flistp = PIN_FLIST_CREATE(ebufp); search_poidp = PIN_POID_CREATE(PIN_POID_GET_DB(poidp), "/search", -1, ebufp); PIN_FLIST_FLD_PUT(flistp, PIN_FLD_POID, (void *)search_poidp, ebufp); int_val = SRCH_DISTINCT; PIN_FLIST_FLD_SET(flistp, PIN_FLD_FLAGS, (void *)&int_val, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_TEMPLATE, (void *)"select X from /account 1, /group 2 where 1.F1 = V1 " "AND 1.F2 = V2 AND 1.F3 = 2.F4 AND 1.F5 != V5 ", ebufp); PIN_FLIST_ELEM_SET(flistp, NULL, PIN_FLD_RESULTS, 0, ebufp); /* * Arg 1 is the type of the account; only interested in brand accounts */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_ACCOUNT_TYPE, (void *)&brand_type, ebufp); /* * Arg 2 is the name of the brand. */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 2, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_NAME, (void *)namep, ebufp); /* * Arg 3 -- POID of account */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 3, ebufp); PIN_FLIST_FLD_PUT(sublistp, PIN_FLD_POID, NULL, ebufp); /* * Arg 4 -- Parent of the group */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 4, ebufp); PIN_FLIST_FLD_PUT(sublistp, PIN_FLD_PARENT, NULL, ebufp); /* * Arg 5 -- POID of current account */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 5, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_POID, poidp, ebufp); /* * Ready to search! Temporarily suspend search to ensure that * all brands are traversed. */ cred = CM_FM_BEGIN_OVERRIDE_SCOPE(CM_CRED_SCOPE_OVERRIDE_ROOT); PCM_OP(ctxp, PCM_OP_GLOBAL_SEARCH, PCM_OPFLG_COUNT_ONLY, flistp, &rlistp, ebufp); CM_FM_END_OVERRIDE_SCOPE(cred); /* * See if there is a brand out there right now that already has * this name. If so, flag it as an error. */ PIN_FLIST_ELEM_GET_NEXT(rlistp, PIN_FLD_RESULTS, &int_val, 1, &cookie, ebufp); if(int_val > 0) { *r_flistpp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(*r_flistpp, PIN_FLD_POID, (void *)poidp, ebufp); fm_cust_pol_valid_add_fail(*r_flistpp, PIN_FLD_NAME, 0, PIN_CUST_VAL_ERR_DUPE, PIN_CUST_DUPE_VALUE_ERR_MSG, (void *)namep, ebufp); pin_set_err(ebufp, PIN_ERRLOC_FM, PIN_ERRCLASS_SYSTEM_DETERMINATE, PIN_ERR_DUPLICATE, PIN_FLD_NAME, 0, 0); } /* * Cleanup and return */ PIN_FLIST_DESTROY_EX(&flistp, NULL); PIN_FLIST_DESTROY_EX(&rlistp, NULL); }
/* * Search for a brand name within a brand. */ static void fm_cust_pol_is_brandname_unique_within_brand( pcm_context_t *ctxp, poid_t *poidp, char *namep, pin_flist_t **r_flistpp, pin_errbuf_t *ebufp) { pin_flist_t *flistp = (pin_flist_t *)NULL; pin_flist_t *rlistp = (pin_flist_t *)NULL; pin_flist_t *sublistp; poid_t *search_poidp; int32 int_val; int32 cred; pin_account_type_t brand_type = PIN_ACCOUNT_TYPE_BRAND; pin_cookie_t cookie = (pin_cookie_t)NULL; pin_flist_t *b_flistp = NULL; pin_flist_t *t_flistp = NULL; poid_t *b_pdp = NULL; poid_t *g_pdp = NULL; poid_t *rootp = NULL; int32 elemid = 0; int under_host = PIN_BOOLEAN_FALSE; void *vp = NULL; /* * If there are pending errors, then short circuit immediately */ if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); fm_utils_lineage_get_brand_hierarchy(ctxp, poidp, &b_flistp, ebufp); if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_is_brandname_unique_within_brand() : " "Call to get brand hierarchy failed ", ebufp); PIN_FLIST_DESTROY_EX (&b_flistp, NULL); fm_cust_pol_read_err_return_list(poidp, namep, r_flistpp, ebufp); goto cleanup; } PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "Got brand hierarchy. Return flist :", b_flistp); t_flistp = PIN_FLIST_ELEM_GET_NEXT(b_flistp, PIN_FLD_RESULTS, &elemid, 1, &cookie, ebufp); if (PIN_ERR_IS_ERR(ebufp) || t_flistp == (pin_flist_t *)NULL) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_is_brandname_unique_within_brand() : " "Call to get first brand failed ", ebufp); PIN_FLIST_DESTROY_EX (&b_flistp, NULL); fm_cust_pol_read_err_return_list(poidp, namep, r_flistpp, ebufp); goto cleanup; } /******************************************** * Get the first brand object from hierarchy ********************************************/ b_pdp = PIN_FLIST_FLD_GET(t_flistp, PIN_FLD_BRAND_OBJ, 0, ebufp); /*************************************************************** * During the brand creation, the first brand object from the * the hierarchy is the parent brand. But, for an existing * brand, the first object is self, the next one in hierarchy * is the parent brand. ***************************************************************/ if (!PIN_POID_COMPARE(b_pdp, poidp, 0, ebufp)) { PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "first brand is self"); t_flistp = PIN_FLIST_ELEM_GET_NEXT(b_flistp, PIN_FLD_RESULTS, &elemid, 1, &cookie, ebufp); if (PIN_ERR_IS_ERR(ebufp) || t_flistp == (pin_flist_t *)NULL) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_is_brandname_unique_within_brand() : " "Call to get second brand failed ", ebufp); PIN_FLIST_DESTROY_EX (&b_flistp, NULL); fm_cust_pol_read_err_return_list(poidp, namep, r_flistpp, ebufp); goto cleanup; } /* Get the parent brand object */ b_pdp = PIN_FLIST_FLD_GET(t_flistp, PIN_FLD_BRAND_OBJ, 0, ebufp); } else { PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "first brand is parent"); } PIN_ERR_LOG_POID(PIN_ERR_LEVEL_DEBUG, "parent brand = ", b_pdp); /*************************************************************** * Check to see if we are creating brand under brandhost ***************************************************************/ rootp = PIN_POID_CREATE(PIN_POID_GET_DB(poidp), "/account", 1, ebufp); if (!PIN_POID_COMPARE(b_pdp, rootp, 0, ebufp)) { under_host = PIN_BOOLEAN_TRUE; /* creating brand under brandhost */ } else { /* creating sub-brand under a brand */ /* get the group_obj_id0 for the parent brand */ cred = CM_FM_BEGIN_OVERRIDE_SCOPE(CM_CRED_SCOPE_OVERRIDE_ROOT); g_pdp = fm_utils_lineage_get_billing_group_by_parent(ctxp, b_pdp, ebufp); CM_FM_END_OVERRIDE_SCOPE(cred); if (PIN_ERR_IS_ERR(ebufp) || g_pdp == (poid_t*)NULL) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_is_brandname_unique_within_brand() : " "Call to get parent group failed ", ebufp); PIN_POID_DESTROY(rootp, NULL); PIN_FLIST_DESTROY_EX (&b_flistp, NULL); fm_cust_pol_read_err_return_list(poidp, namep, r_flistpp, ebufp); goto cleanup; } } PIN_POID_DESTROY(rootp, NULL); PIN_FLIST_DESTROY_EX (&b_flistp, NULL); /* * Create search flist to try to figure out if someother brand already * has this name within the parent brand. */ flistp = PIN_FLIST_CREATE(ebufp); search_poidp = PIN_POID_CREATE(PIN_POID_GET_DB(poidp), "/search", -1, ebufp); PIN_FLIST_FLD_PUT(flistp, PIN_FLD_POID, (void *)search_poidp, ebufp); int_val = SRCH_DISTINCT; PIN_FLIST_FLD_SET(flistp, PIN_FLD_FLAGS, (void *)&int_val, ebufp); /*************************************************************** * We need different search templates for checking duplicate * brandnames under the brandhost or another brand. * The brandhost doesnot have an entry in the /group/billing * storable class. The only way we can get the names of the * existing brands under the brandhost is to check the lineage * tag. Arguments 1 to 3 are the same for both search templates, * but arguments 4 & 5 are different. ***************************************************************/ if (under_host == PIN_BOOLEAN_FALSE) { /* creating sub-brands under a brand */ PIN_FLIST_FLD_SET(flistp, PIN_FLD_TEMPLATE, (void *)TEMPLATE_UNIQUE_UNDER_BRAND, ebufp); } else { /* creating brand under brandhost */ PIN_FLIST_FLD_SET(flistp, PIN_FLD_TEMPLATE, (void *)TEMPLATE_UNIQUE_UNDER_BRANDHOST, ebufp); } PIN_FLIST_ELEM_SET(flistp, NULL, PIN_FLD_RESULTS, 0, ebufp); /* * Arg 1 is the type of the account; only interested in brand accounts */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_ACCOUNT_TYPE, (void *)&brand_type, ebufp); /* * Arg 2 is the name of the brand. */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 2, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_NAME, (void *)namep, ebufp); /* * Arg 3 -- POID of account */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 3, ebufp); PIN_FLIST_FLD_PUT(sublistp, PIN_FLD_POID, NULL, ebufp); if (under_host == PIN_BOOLEAN_FALSE) { /* creating sub-brands under a brand */ /* * Arg 4 -- OBJECT_ID of members from /group/billing */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 4, ebufp); sublistp = PIN_FLIST_ELEM_ADD(sublistp, PIN_FLD_MEMBERS, PIN_ELEMID_ANY, ebufp); PIN_FLIST_FLD_PUT(sublistp, PIN_FLD_OBJECT, (void *)NULL, ebufp); /* * Arg 5 -- POID of the group */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 5, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_POID, (void *)g_pdp, ebufp); } else { /* creating brand under brandhost */ /* * Arg 4 -- Parent of the group */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 4, ebufp); PIN_FLIST_FLD_PUT(sublistp, PIN_FLD_PARENT, NULL, ebufp); /* * Arg 5 -- LINEAGE of account */ /* accounts under brandhost have only one ":" in their lineage tag. We want to exclude others. */ vp = (void *)"%:%:%"; sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 5, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_LINEAGE, vp, ebufp); } /* * Arg 6 -- POID of current account */ sublistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 6, ebufp); PIN_FLIST_FLD_SET(sublistp, PIN_FLD_POID, poidp, ebufp); /* * For completeness, dump the input flist if debugging is enabled. */ PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "fm_cust_pol_is_brandname_unique_within_brand search input flist:", flistp); /* * Ready to search! Temporarily suspend search to ensure that * all brands are traversed. */ cred = CM_FM_BEGIN_OVERRIDE_SCOPE(CM_CRED_SCOPE_OVERRIDE_ROOT); PCM_OP(ctxp, PCM_OP_GLOBAL_SEARCH, PCM_OPFLG_COUNT_ONLY, flistp, &rlistp, ebufp); CM_FM_END_OVERRIDE_SCOPE(cred); /* * For completeness, dump the results flist if debugging is enabled * and we actually have a results flist. */ if(rlistp != (pin_flist_t *)NULL) { PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "fm_cust_pol_is_brandname_unique_within_brand search output flist:", rlistp); } /* * See if there is a brand out there right now that already has * this name. If so, flag it as an error. */ cookie = (pin_cookie_t)NULL; int_val = 0; PIN_FLIST_ELEM_GET_NEXT(rlistp, PIN_FLD_RESULTS, &int_val, 1, &cookie, ebufp); if(int_val > 0) { *r_flistpp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(*r_flistpp, PIN_FLD_POID, (void *)poidp, ebufp); fm_cust_pol_valid_add_fail(*r_flistpp, PIN_FLD_NAME, 0, PIN_CUST_VAL_ERR_DUPE, PIN_CUST_DUPE_VALUE_ERR_MSG, (void *)namep, ebufp); pin_set_err(ebufp, PIN_ERRLOC_FM, PIN_ERRCLASS_SYSTEM_DETERMINATE, PIN_ERR_DUPLICATE, PIN_FLD_NAME, 0, 0); } cleanup: /* * Cleanup and return */ PIN_FLIST_DESTROY_EX(&flistp, NULL); PIN_FLIST_DESTROY_EX(&rlistp, NULL); PIN_POID_DESTROY(g_pdp, NULL); }
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); } }
static void fm_pymt_pol_spec_collect_get_items( pcm_context_t *ctxp, int32 flags, pin_flist_t *i_flistp, pin_flist_t *o_flistp, pin_errbuf_t *ebufp) { pin_flist_t *items_flistp = NULL; pin_flist_t *r_flistp = NULL; pin_flist_t *flistp = NULL; poid_t *s_pdp = NULL; poid_t *bi_pdp = NULL; int32 status = 0; int64 database = 0; int32 sflags = SRCH_DISTINCT; int32 result = PIN_BOOLEAN_FALSE; void *vp = NULL; pin_decimal_t *zero_decimal = pin_decimal("0.0", ebufp); if (PIN_ERR_IS_ERR(ebufp)) { return; } PIN_ERR_CLEAR_ERR(ebufp); /********************************************************* * Get the ACH details. *********************************************************/ fm_pymt_pol_spec_collect_get_ach(ctxp, flags, i_flistp, o_flistp, ebufp); bi_pdp = PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_BILLINFO_OBJ, 0, ebufp); /********************************************************* * Create the search flist to search in the item objects *********************************************************/ items_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(items_flistp, PIN_FLD_POID, (void *)s_pdp, ebufp); PIN_FLIST_FLD_SET(items_flistp, PIN_FLD_TEMPLATE, (void *) "select X from /item where F1 = V1 and ( F2 = V2 or F3 = V3 )" \ " and F4 != V4 order by F5 ", ebufp); PIN_FLIST_FLD_SET(items_flistp, PIN_FLD_FLAGS, (void *)&sflags, ebufp); /********************************************************* * Add the search arguments. *********************************************************/ flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_AR_BILLINFO_OBJ, (void *)bi_pdp, ebufp); status = PIN_ITEM_STATUS_PENDING; flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_ARGS, 2, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS, (void *)&status, ebufp); status = PIN_ITEM_STATUS_OPEN; flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_ARGS, 3, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS, (void *)&status, ebufp); flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_ARGS, 4, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_DUE, (void *)zero_decimal, ebufp); flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_ARGS, 5, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_EFFECTIVE_T, (void *)NULL, ebufp); /********************************************************* * Add the results array for the search. *********************************************************/ flistp = PIN_FLIST_ELEM_ADD(items_flistp, PIN_FLD_RESULTS, 0, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_POID,(void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_BILL_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_AR_BILL_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_ACCOUNT_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_DUE,(void *) NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_EFFECTIVE_T, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_ITEM_TOTAL, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_DISPUTED, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_RECVD, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_ADJUSTED, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_TRANSFERED, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_CURRENCY, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_ITEM_NO, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_BILLINFO_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_AR_BILLINFO_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_SERVICE_OBJ, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_EVENT_POID_LIST, (void *)NULL, ebufp); /********************************************************** * search ALL Open and Pending items **********************************************************/ PCM_OP(ctxp, PCM_OP_SEARCH, PCM_OPFLG_READ_UNCOMMITTED , items_flistp, &r_flistp,ebufp); if (PIN_FLIST_FLD_COPY(r_flistp, PIN_FLD_RESULTS, o_flistp, PIN_FLD_ITEMS, ebufp) == 1) { result = PIN_BOOLEAN_TRUE; } PIN_FLIST_FLD_SET(o_flistp, PIN_FLD_BOOLEAN, (void *)&result, ebufp); /********************************************************* * Cleanup... *********************************************************/ PIN_FLIST_DESTROY_EX(&items_flistp, NULL); PIN_FLIST_DESTROY_EX(&r_flistp, NULL); PIN_DECIMAL_DESTROY_EX(&zero_decimal); /********************************************************* * Errors..? *********************************************************/ if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_pymt_pol_spec_collect_get_items error", ebufp); } return; }
/******************************************************************** * fm_cust_pol_get_poplist() * * Obtains a list of pops and adds to the given outflistp. * If no PIN_FLD_ANI is found on the input flist, then the * entire pop list is returned. Otherwise, only the POP * matching the ANI is returned. * ********************************************************************/ static void fm_cust_pol_get_poplist( pcm_context_t *ctxp, /* Connection context */ pin_flist_t *in_flistp, /* Client's input flist */ pin_flist_t *out_flistp, /* Search results flist */ pin_errbuf_t *ebufp) /* Error buff */ { u_int64 database; /* Requested database */ poid_t *poidp = NULL; /* Input poid */ poid_t *objp = NULL; /* New search poid */ poid_t *type_poidp; /* Used for full poplist*/ pin_cookie_t cookie = NULL; /* For getting results */ pin_cookie_t cookie2 = NULL; /* For getting anis */ pin_flist_t *flistp = NULL; /* Search flist created */ pin_flist_t *ani_flistp = NULL; /* ANI array flist */ pin_flist_t *a_flistp = NULL; /* New element pointer */ pin_flist_t *e_flistp = NULL; /* Element ptr 4 pop arr*/ pin_flist_t *r_flistp = NULL; /* Search return flist */ pin_flist_t *sort_flistp = NULL; /* Sort flist */ u_int64 id; /* Search id */ u_int type = POP_PRIMARY; /* Only return prime pop*/ int32 rec_id; /* PIN_FLD_RESULTS elem */ int32 rec_id2; /* ANI results elem */ void *vp; /* PIN_FLD_ANI value */ void *vp2; /* Returned fields ptr */ /*********************************************************** * Check the error buffer. ***********************************************************/ if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); /*********************************************************** * Allocate the flist for searching. ***********************************************************/ flistp = PIN_FLIST_CREATE(ebufp); /*********************************************************** * Get the database number. ***********************************************************/ poidp = (poid_t *)PIN_FLIST_FLD_GET(in_flistp, PIN_FLD_POID, 0, ebufp); database = PIN_POID_GET_DB(poidp); /*********************************************************** * Allocate the search poid and give it to the flist. Use * the 2 arg search id if args are found, otherwise use * the 1 arg search which returns all the pops ordered. ***********************************************************/ vp = PIN_FLIST_FLD_GET(in_flistp, PIN_FLD_ANI, 1, ebufp); if (vp == NULL) { id = (u_int64)300; } else { id = (u_int64)301; } objp = PIN_POID_CREATE(database, "/search/pin", id, ebufp); PIN_FLIST_FLD_PUT(flistp, PIN_FLD_POID, (void *)objp, ebufp); /*********************************************************** * Add a search arguments array. ***********************************************************/ a_flistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 1, ebufp); /*********************************************************** * Determine whether the entire poplist should be returned * or an ani to pop match should be done. The rule is if * there's a PIN_FLD_ANI field, return the entire list, * otherwise, do a ani to pop match but only return the * primary one. ***********************************************************/ type_poidp = PIN_POID_CREATE(database, "/pop", (int64)-1, ebufp); if (vp == NULL) { PIN_FLIST_FLD_PUT(a_flistp, PIN_FLD_POID, (void *)type_poidp, ebufp); } else { /* ** 2 arg search, return pop that matches ani and is a ** primary pop. */ ani_flistp = PIN_FLIST_CREATE(ebufp); /* ** PIN_FLD_ANI for our first arg. */ PIN_FLIST_FLD_SET(ani_flistp, PIN_FLD_ANI, vp, ebufp ); PIN_FLIST_ELEM_SET(a_flistp, ani_flistp, PIN_FLD_ANIS, 0, ebufp ); /* ** PIN_FLD_TYPE for our second arg. */ a_flistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_ARGS, 2, ebufp); ani_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(ani_flistp, PIN_FLD_TYPE, (void *)&type, ebufp); PIN_FLIST_ELEM_SET(a_flistp, ani_flistp, PIN_FLD_ANIS, 1, ebufp); } /*********************************************************** * Put on the PIN_FLD_RESULTS array for our results. ***********************************************************/ a_flistp = PIN_FLIST_ELEM_ADD(flistp, PIN_FLD_RESULTS, 0, ebufp); /* ** Return the pop, city, state and zip fields if the entire poplist ** was requested, otherwise return the same fields including ** the flags if pop matching was requested. */ PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_PHONE, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_CITY, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_STATE, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_ZIP, (void *)NULL, ebufp); if (vp != NULL) { /* ** Add the ANIS array if PIN_FLD_ANI arg was passed in. */ ani_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(ani_flistp, PIN_FLD_ANI, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(ani_flistp, PIN_FLD_TYPE, (void *)NULL, ebufp); PIN_FLIST_FLD_SET(ani_flistp, PIN_FLD_FLAGS, (void *)NULL, ebufp); PIN_FLIST_ELEM_SET(a_flistp, ani_flistp, PIN_FLD_ANIS, 0, ebufp); } /*********************************************************** * Call the DM to do the search. ***********************************************************/ PCM_OP(ctxp, PCM_OP_SEARCH, 0, flistp, &r_flistp, ebufp); /*********************************************************** * Walk the search results array adding each to the * PIN_FLD_POP's array flist to pass back to the caller. ***********************************************************/ a_flistp = PIN_FLIST_ELEM_GET_NEXT(r_flistp, PIN_FLD_RESULTS, &rec_id, 1, &cookie, ebufp); while (a_flistp != (pin_flist_t *)NULL) { e_flistp = PIN_FLIST_ELEM_ADD(out_flistp, PIN_FLD_POP, rec_id, ebufp); /* ** Take the PIN_FLD_PHONE and put it on the PIN_FLD_POP array. */ vp2 = PIN_FLIST_FLD_TAKE(a_flistp, PIN_FLD_PHONE, 0, ebufp); PIN_FLIST_FLD_PUT(e_flistp, PIN_FLD_PHONE, vp2, ebufp); /* ** Take the PIN_FLD_CITY and put it on the PIN_FLD_POP array. */ vp2 = PIN_FLIST_FLD_TAKE(a_flistp, PIN_FLD_CITY, 0, ebufp); PIN_FLIST_FLD_PUT(e_flistp, PIN_FLD_CITY, vp2, ebufp); /* ** Take the PIN_FLD_STATE and put it on the PIN_FLD_POP array. */ vp2 = PIN_FLIST_FLD_TAKE(a_flistp, PIN_FLD_STATE, 0, ebufp); PIN_FLIST_FLD_PUT(e_flistp, PIN_FLD_STATE, vp2, ebufp); /* ** Take the PIN_FLD_ZIP and put it on the PIN_FLD_POP array. */ vp2 = PIN_FLIST_FLD_TAKE(a_flistp, PIN_FLD_ZIP, 0, ebufp); PIN_FLIST_FLD_PUT(e_flistp, PIN_FLD_ZIP, vp2, ebufp); /* ** Walk the ani array (if we're pop matching) to get the ** PIN_FLD_FLAGS field, should only be one. */ if (vp != NULL) { ani_flistp = (pin_flist_t *)NULL; ani_flistp = PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_ANIS, &rec_id2, 0, &cookie2, ebufp); while (ani_flistp != (pin_flist_t *)NULL) { vp2 = PIN_FLIST_FLD_TAKE(ani_flistp, PIN_FLD_FLAGS, 0, ebufp); PIN_FLIST_FLD_PUT(e_flistp, PIN_FLD_FLAGS, vp2, ebufp); ani_flistp = PIN_FLIST_ELEM_GET_NEXT(a_flistp, PIN_FLD_ANIS, &rec_id2, 1, &cookie2, ebufp); } } /*************************************************** * Get the next result. ***************************************************/ a_flistp = PIN_FLIST_ELEM_GET_NEXT(r_flistp, PIN_FLD_RESULTS, &rec_id, 1, &cookie, ebufp); } /*********************************************************** * Clean up. ***********************************************************/ PIN_FLIST_DESTROY(flistp, NULL); PIN_FLIST_DESTROY(r_flistp, NULL); if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_read_poplist error", ebufp); } return; } /* fm_cust_pol_read_poplist */
/**************************************************************** * Function : fm_cust_pol_prep_create_sponsored_topup * Description : This function will prepare the flist for * creating the sponsored topup operation. ****************************************************************/ static void fm_cust_pol_prep_create_sponsored_topup( pcm_context_t *ctxp, int32 flags, pin_flist_t *i_flistp, pin_flist_t **r_flistpp, pin_errbuf_t *ebufp) { poid_t *initiator_pdp = NULL; poid_t *parent_pdp = NULL; poid_t *balgrp_pdp = NULL; poid_t *s_pdp = NULL; poid_t *grp_pdp = NULL; pin_flist_t *topup_flistp = NULL; pin_flist_t *ingrptopup_flistp = NULL; pin_flist_t *ingrplmt_flistp = NULL; pin_flist_t *ingrpmem_flistp = NULL; pin_flist_t *tmp_flistp = NULL; pin_flist_t *args1_flistp = NULL; pin_flist_t *args2_flistp = NULL; pin_flist_t *args3_flistp = NULL; pin_flist_t *outtopup_flistp = NULL; pin_flist_t *outgrpmem_flistp = NULL; pin_flist_t *outgrptopup_flistp= NULL; pin_flist_t *reslt_flistp = NULL; pin_flist_t *f_flistp = NULL; pin_flist_t *s_flistp = NULL; pin_flist_t *r_flistp = NULL; char *grp_name = NULL; char *s_tmplt = NULL; int *res_id = NULL; int *topup_interval = NULL; int64 db_no = 0; int search_flag = 256; time_t nexttopup; time_t now; void *vp; if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); initiator_pdp = PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_POID, 0, ebufp); topup_flistp = PIN_FLIST_ELEM_GET(i_flistp, PIN_FLD_TOPUP_INFO, PIN_ELEMID_ANY, 0, ebufp); ingrptopup_flistp = PIN_FLIST_ELEM_GET(topup_flistp, PIN_FLD_GROUP_TOPUP_INFO, PIN_ELEMID_ANY, 0, ebufp); ingrpmem_flistp = PIN_FLIST_ELEM_GET(ingrptopup_flistp, PIN_FLD_GROUP_TOPUP_MEMBERS, PIN_ELEMID_ANY, 0, ebufp); ingrplmt_flistp = PIN_FLIST_ELEM_GET(ingrptopup_flistp, PIN_FLD_GROUP_TOPUP_LIMITS, PIN_ELEMID_ANY, 0, ebufp); /**************************************************************** * Update the NEXT_TOPUP_T in the out put flist. ****************************************************************/ outtopup_flistp = PIN_FLIST_ELEM_GET(*r_flistpp, PIN_FLD_TOPUP_INFO, PIN_ELEMID_ANY, 0, ebufp); outgrptopup_flistp = PIN_FLIST_ELEM_GET(outtopup_flistp, PIN_FLD_GROUP_TOPUP_INFO, PIN_ELEMID_ANY, 0, ebufp); outgrpmem_flistp = PIN_FLIST_ELEM_GET(outgrptopup_flistp, PIN_FLD_GROUP_TOPUP_MEMBERS, PIN_ELEMID_ANY, 0, ebufp); topup_interval = PIN_FLIST_FLD_GET(outgrpmem_flistp, PIN_FLD_TOPUP_INTERVAL, 0, ebufp); if (PIN_ERR_IS_ERR(ebufp)) return; vp = PIN_FLIST_FLD_GET(ingrpmem_flistp , PIN_FLD_NEXT_TOPUP_T, 1, ebufp); if(vp){ PIN_FLIST_FLD_SET(outgrpmem_flistp, PIN_FLD_NEXT_TOPUP_T, vp, ebufp); }else{ now = pin_virtual_time((time_t *) NULL); nexttopup = now + ((*topup_interval) * 24 * 60 * 60 ); PIN_FLIST_FLD_SET(outgrpmem_flistp, PIN_FLD_NEXT_TOPUP_T, &nexttopup, ebufp); } grp_name = PIN_FLIST_FLD_GET(ingrptopup_flistp, PIN_FLD_NAME, 1, ebufp); grp_pdp = PIN_FLIST_FLD_GET(ingrptopup_flistp, PIN_FLD_POID, 0, ebufp); /**************************************************************** * check if the group poid is type only or not and also * it has the name or not. ****************************************************************/ if( PIN_POID_IS_TYPE_ONLY(grp_pdp) || !grp_name ) { /**************************************************************** * If the group name or the group poid is not defind in the * input flist then search /group/topup for the particular * parent and set the name and the group poid. ****************************************************************/ parent_pdp = PIN_FLIST_FLD_GET(ingrptopup_flistp, PIN_FLD_PARENT, 0, ebufp); balgrp_pdp = PIN_FLIST_FLD_GET(ingrptopup_flistp, PIN_FLD_BAL_GRP_OBJ, 0, ebufp); res_id = PIN_FLIST_FLD_GET(ingrplmt_flistp, PIN_FLD_RESOURCE_ID, 0, ebufp); db_no = PIN_POID_GET_DB(initiator_pdp); s_flistp = PIN_FLIST_CREATE(ebufp); s_pdp = PIN_POID_CREATE(db_no, "/search", -1, ebufp); s_tmplt = " select X from /group/topup where F1 = V1 and F2 = V2 and F3 = V3 "; PIN_FLIST_FLD_PUT(s_flistp, PIN_FLD_POID, s_pdp, ebufp); PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_TEMPLATE, s_tmplt, ebufp); PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_FLAGS, &search_flag, ebufp); tmp_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(tmp_flistp, PIN_FLD_PARENT, parent_pdp, ebufp); args1_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(args1_flistp, PIN_FLD_BAL_GRP_OBJ, balgrp_pdp, ebufp); f_flistp = PIN_FLIST_CREATE(ebufp); if( grp_name == NULL ) { /**************************************************************** * if the group name is null then the search argument will contain * the resource id. ****************************************************************/ args3_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(f_flistp, PIN_FLD_RESOURCE_ID, res_id, ebufp); PIN_FLIST_ELEM_PUT(args3_flistp, f_flistp, PIN_FLD_GROUP_TOPUP_LIMITS, PCM_RECID_ALL, ebufp); PIN_FLIST_ELEM_PUT(s_flistp, args3_flistp, PIN_FLD_ARGS, 3, ebufp); } else { PIN_FLIST_FLD_SET(f_flistp, PIN_FLD_NAME, grp_name, ebufp); PIN_FLIST_ELEM_PUT(s_flistp, f_flistp, PIN_FLD_ARGS, 3, ebufp); } PIN_FLIST_ELEM_PUT(s_flistp, tmp_flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_ELEM_PUT(s_flistp, args1_flistp, PIN_FLD_ARGS, 2, ebufp); reslt_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(reslt_flistp, PIN_FLD_NAME, "",ebufp); PIN_FLIST_ELEM_PUT(s_flistp, reslt_flistp, PIN_FLD_RESULTS, 0, ebufp); PCM_OP(ctxp, PCM_OP_SEARCH, flags, s_flistp, &r_flistp, ebufp); PIN_FLIST_DESTROY_EX(&s_flistp, NULL); tmp_flistp = PIN_FLIST_ELEM_GET(r_flistp, PIN_FLD_RESULTS, 0, 1, ebufp); /**************************************************************** * If the results array of search contains any record then select the * finst element of the results array and set the group poid and name * else don't set it. ****************************************************************/ if( tmp_flistp != NULL ) { grp_name = PIN_FLIST_FLD_GET(tmp_flistp, PIN_FLD_NAME, 0, ebufp); grp_pdp = PIN_FLIST_FLD_GET(tmp_flistp, PIN_FLD_POID, 0, ebufp); f_flistp = PIN_FLIST_ELEM_GET(outtopup_flistp, PIN_FLD_GROUP_TOPUP_INFO, PIN_ELEMID_ANY, 0, ebufp); PIN_FLIST_FLD_SET(f_flistp, PIN_FLD_NAME, grp_name, ebufp); PIN_FLIST_FLD_SET(f_flistp, PIN_FLD_POID, grp_pdp, ebufp); } PIN_FLIST_DESTROY_EX(&r_flistp, NULL); } if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_prep_create_sponsored_topup error", ebufp); } return; }
/******************************************************************* * fm_pymt_pol_collect_result_soft(): * * Create the collect result for 'soft' pin declines. * * All soft declines are subject to the same rules, but * we may need/want to treat each command differently. * *******************************************************************/ static void fm_pymt_pol_collect_result_soft( pcm_context_t *ctxp, pin_flist_t *i_flistp, pin_flist_t *r_flistp, pin_errbuf_t *ebufp) { pin_flist_t *a_flistp = NULL; pin_flist_t *b_flistp = NULL; pin_flist_t *flistp = NULL; pin_cookie_t cookie = NULL; int result; int rec_id; char *descr = NULL; pin_status_t *status = NULL; int *flags = NULL; poid_t *a_pdp = NULL; poid_t *s_pdp = NULL; poid_t *b_pdp = NULL; void *vp = NULL; char *templatep; int32 srch_flags = SRCH_DISTINCT; int item_status = PIN_ITEM_STATUS_OPEN; pin_decimal_t *item_due = NULL; time_t start_t = 0; if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); item_due = pbo_decimal_from_str("0.01", ebufp); /*********************************************************** * All get the FAIL result and default descr. ***********************************************************/ result = PIN_RESULT_FAIL; PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "creditcard operation declined"; PIN_FLIST_FLD_SET(r_flistp, PIN_FLD_DESCR, (void *)descr, ebufp); /*********************************************************** * Read the config info. ***********************************************************/ fm_pymt_pol_collect_config(ctxp, i_flistp, &b_flistp, ebufp); /*********************************************************** * If not already inactive for debt/closed, suspend. ***********************************************************/ status = (pin_status_t *)PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_STATUS, 0, ebufp); flags = (int *)PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_STATUS_FLAGS, 0, ebufp); a_pdp = (poid_t *)PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_POID, 0, ebufp); b_pdp = (poid_t *)PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_LAST_BILL_OBJ, 0, ebufp); /*********************************************************** * Nothing to do, if there was no last bill object. ***********************************************************/ if (PIN_POID_IS_NULL(b_pdp)) { PIN_FLIST_DESTROY_EX(&b_flistp, NULL); pbo_decimal_destroy(&item_due); return; } /*********************************************************** * Read the bill object for the start of the billing cycle. ***********************************************************/ vp = (void *)NULL; a_flistp = PIN_FLIST_CREATE(ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_POID, (void *)b_pdp, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_START_T, vp, ebufp); /*********************************************************** * Read the info from the last bill object. ***********************************************************/ PCM_OP(ctxp, PCM_OP_READ_FLDS, 0, a_flistp, &flistp, ebufp); vp = PIN_FLIST_FLD_GET(flistp, PIN_FLD_START_T, 0,ebufp); if (vp) start_t = *((time_t *)vp); PIN_FLIST_DESTROY_EX(&a_flistp, NULL); PIN_FLIST_DESTROY_EX(&flistp, NULL); /*********************************************************** * Allocate the flist for search the item objects. ***********************************************************/ a_flistp = PIN_FLIST_CREATE(ebufp); /************************************************************** * Construct the search poid. **************************************************************/ s_pdp = PIN_POID_CREATE(PIN_POID_GET_DB(a_pdp), "/search/pin", -1, ebufp); PIN_FLIST_FLD_PUT(a_flistp, PIN_FLD_POID, (void *)s_pdp, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_FLAGS, &srch_flags, ebufp); /************************************************************** * Specify the search arguments. **************************************************************/ flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_ACCOUNT_OBJ, (void *)a_pdp, ebufp); flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_ARGS, 2, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_STATUS, (void *)&item_status, ebufp); flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_ARGS, 3, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_DUE, (void *)item_due, ebufp); flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_ARGS, 4, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_EFFECTIVE_T, (void *)&start_t, ebufp); templatep = "select X from /item/$1 " " where F1 = V1 " " and F2 = V2 " " and F3 >= V3 " " and F4 <= V4 "; PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_TEMPLATE, (void *)templatep, ebufp); /************************************************************** * Set-up the results array. **************************************************************/ vp = (void *)NULL; flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_RESULTS, 0, ebufp); PIN_FLIST_FLD_SET(flistp, PIN_FLD_POID, vp, ebufp); /************************************************************** * Call the PCM_OP_SEARCH opcode to do the actual search. **************************************************************/ PCM_OP(ctxp, PCM_OP_SEARCH, 0, a_flistp, &flistp, ebufp); PIN_FLIST_DESTROY_EX(&a_flistp, NULL); /************************************************************** * Did we find any items with 30 days due. **************************************************************/ a_flistp = PIN_FLIST_ELEM_GET_NEXT(flistp, PIN_FLD_RESULTS, &rec_id, 1, &cookie, ebufp); if ((a_flistp != (pin_flist_t *)NULL) && (status)) { switch (*status) { case PIN_STATUS_INACTIVE: if (flags && (*flags & PIN_STATUS_FLAG_DEBT)) break; /* intentional fall-thru */ case PIN_STATUS_ACTIVE: fm_pymt_pol_collect_set_status(r_flistp, PIN_STATUS_INACTIVE, PIN_STATUS_FLAG_DEBT, "credit card pastdue", ebufp); break; case PIN_STATUS_CLOSED: break; default: break; } } /*********************************************************** * Someday check for age of debt and close after so long. ***********************************************************/ /*********************************************************** * Cleanup. ***********************************************************/ PIN_FLIST_DESTROY_EX(&b_flistp, NULL); PIN_FLIST_DESTROY_EX(&flistp, NULL); pbo_decimal_destroy(&item_due); /* Error? - caught/logged by caller */ return; }
/******************************************************************* * fm_cust_pol_get_plans() * * Retrieves the appropriate plan_list object from the db. * Then performs a read_obj of each plan in the list. The * result is an array of available plans for the relevant * aac method (mecca, admin, etc). * *******************************************************************/ static void fm_cust_pol_get_plans( pcm_context_t *ctxp, pin_flist_t *i_flistp, pin_flist_t **o_flistpp, pin_errbuf_t *ebufp) { pin_flist_t *p_flistp = NULL; pin_flist_t *r_flistp = NULL; poid_t *pdp = NULL; int64 brand_db = 0; int64 planlist_db = 0; if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); /* * Get the database of brand. */ PCM_OP(ctxp, PCM_OP_PERM_GET_CREDENTIALS, 0, i_flistp, &r_flistp, ebufp); pdp = (poid_t *)PIN_FLIST_FLD_GET(r_flistp, PIN_FLD_BRAND_OBJ, 0, ebufp); if ( PIN_POID_GET_ID(pdp) == 1 ) { /* * this has the root brand so * Get the database number of the input PIN_FLD_POID. */ pdp = (poid_t *)PIN_FLIST_FLD_GET(i_flistp, PIN_FLD_POID, 0, ebufp); } brand_db = PIN_POID_GET_DB(pdp); PIN_FLIST_DESTROY_EX( &r_flistp, NULL ); /* * Figure out the database where the plan lists are located. * * The /group/plan_list is the only pricelist object that * does not get replicated in a multidb configuration currently * and resides ONLY in the primary database. */ if (cm_fm_is_multi_db() ) { cm_fm_get_primary_db_no(&planlist_db, ebufp); } else { planlist_db = brand_db; } /* * Locate the desired plan_list */ fm_cust_pol_get_plans_locate(ctxp, planlist_db, i_flistp, &p_flistp, ebufp); /* * Read the plans on the list */ fm_cust_pol_get_plans_retrieve(ctxp, brand_db, i_flistp, p_flistp, o_flistpp, ebufp); /* * Error? */ if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_cust_pol_get_plans error", ebufp); } PIN_FLIST_DESTROY_EX(&p_flistp, NULL); return; }
/******************************************************************* * 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; }
/******************************************************************* * Main routine for the PCM_OP_PYMT_POL_PRE_COLLECT command *******************************************************************/ void op_pymt_pol_pre_collect( cm_nap_connection_t *connp, int opcode, int flags, pin_flist_t *in_flistp, pin_flist_t **ret_flistpp, pin_errbuf_t *ebufp) { pcm_context_t *ctxp = connp->dm_ctx; pin_cookie_t cookie = NULL; pin_flist_t *flistp = NULL; pin_flist_t *c_flistp = NULL; pin_flist_t *chkpt_flistp = NULL; pin_flist_t *rc_flistp = NULL; pin_charge_cmd_t *cmdp = NULL; pin_decimal_t *amtp = NULL; poid_t *a_pdp = NULL; double *d_ptr = NULL; char *descr = NULL; int32 *selectp = NULL; int32 elemid = 0; int32 result = 0; int32 err = 0; int32 flag = 0; int32 sflag = 0; int32 rec_id = 0; pin_decimal_t *minimum_pay = NULL; pin_decimal_t *minimum_ref = NULL; pin_flist_t *s_flistp = NULL; pin_flist_t *a_flistp = NULL; pin_flist_t *b_flistp = NULL; pin_flist_t *r_flistp = NULL; poid_t *s_pdp = NULL; int32 *mandate_status = 0; pin_pymt_result_t *statusp = NULL; int32 *resultp = NULL; char vendor_name[256] = {" "}; void *vp = NULL; char *dd_vendorp = NULL; if (PIN_ERR_IS_ERR(ebufp)) return; PIN_ERR_CLEAR_ERR(ebufp); /*********************************************************** * Null out results until we have some. ***********************************************************/ *ret_flistpp = (pin_flist_t *)NULL; /*********************************************************** * Insanity check. ***********************************************************/ if (opcode != PCM_OP_PYMT_POL_PRE_COLLECT) { 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, "bad opcode in op_pymt_pol_pre_collect", ebufp); return; } /*********************************************************** * Debug: What did we get? ***********************************************************/ PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "op_pymt_pol_pre_collect input flist", in_flistp); /*********************************************************** * Get command from very first element of array * note: we cannot rely that it has index [0] or [1] or ... ***********************************************************/ flistp = PIN_FLIST_ELEM_GET_NEXT(in_flistp, PIN_FLD_CHARGES, &elemid, 0, &cookie, ebufp); cmdp = (pin_charge_cmd_t *)PIN_FLIST_FLD_GET(flistp, PIN_FLD_COMMAND, 0, ebufp); /*********************************************************** * Select the list of outstanding checkpoint events. * Checkpoints' existance has sense for following commands only: * authorization, deposit, conditional deposit and refund ***********************************************************/ if (cmdp && ((*cmdp == PIN_CHARGE_CMD_CONDITION) || (*cmdp == PIN_CHARGE_CMD_REFUND) || (*cmdp == PIN_CHARGE_CMD_AUTH_ONLY) || (*cmdp == PIN_CHARGE_CMD_DEPOSIT))) { /*********************************************************** * New algorithm is to search for checkpoint upfront and * pass a flag that indicates that search is done ***********************************************************/ pin_flist_t *b_flistp = NULL; int32 *b_flags = 0; /*********************************************************** * Get checkpoints' flag from very first element of array * note: we cannot rely that it has index [0] or [1] or ... ***********************************************************/ elemid = 0; cookie = NULL; b_flistp = PIN_FLIST_ELEM_GET_NEXT(in_flistp,PIN_FLD_BATCH_INFO, &elemid, 1, &cookie, ebufp); if (b_flistp != 0) { b_flags = (int32*)PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_STATUS_FLAGS, 1, ebufp); } /*********************************************************** * 1. If no flags do checkpoints selection * 2. If flag is not set do checkpoint selection * 3. If flag is set don't perform checkpoint selection ***********************************************************/ if(!((b_flags != 0)&&(*b_flags & PIN_PAYMENT_BATCH_CHKPTS))){ fm_pymt_pol_find_outstanding_chkpts(ctxp, in_flistp, &chkpt_flistp, ebufp); } } /*********************************************************** * Get the minimum charge amount from the pin.conf. If the * entry is missing from the pin.conf assume the default * minimum value of 2.00 ***********************************************************/ pin_conf("fm_pymt_pol", "minimum_payment", PIN_FLDT_NUM, (caddr_t *)&d_ptr, &err); if (d_ptr) { minimum_pay = pbo_decimal_from_double(*d_ptr, ebufp); free(d_ptr); } else { minimum_pay = pbo_decimal_from_str("2.00", ebufp); } /*********************************************************** * Get the minimum refund amount from the pin.conf. If the * entry is missing from the pin.conf assume the default * minimum value of -2.00 ***********************************************************/ pin_conf("fm_pymt_pol", "minimum_refund", PIN_FLDT_NUM, (caddr_t *)&d_ptr, &err); if (d_ptr) { minimum_ref = pbo_decimal_from_double(*d_ptr, ebufp); free(d_ptr); } else { minimum_ref = pbo_decimal_from_str("2.00", ebufp); } /*********************************************************** * Get the dd_vendor value from the pin.conf. ***********************************************************/ pin_conf("cm", "dd_vendor", PIN_FLDT_STR, (caddr_t *)&dd_vendorp, &err); c_flistp = PIN_FLIST_COPY(in_flistp, ebufp); /*********************************************************** * Walk the charges array and check each element. ***********************************************************/ elemid = 0; cookie = NULL; while ((flistp = PIN_FLIST_ELEM_GET_NEXT(c_flistp, PIN_FLD_CHARGES, &elemid, 1, &cookie, ebufp)) != (pin_flist_t *)NULL) { statusp = (pin_pymt_result_t *) PIN_FLIST_FLD_GET(flistp, PIN_FLD_STATUS, 1, ebufp); resultp = (int32 *) PIN_FLIST_FLD_GET(flistp,PIN_FLD_RESULT, 1, ebufp); if((statusp && *statusp >= PIN_PYMT_SUSPENSE && *statusp < PIN_PYMT_FAILED) || (resultp && *resultp == PIN_PAYMENT_RES_FAIL)){ /******************************************* * Do nothing if a payment in suspense *******************************************/ continue; } amtp = (pin_decimal_t *)PIN_FLIST_FLD_GET(flistp, PIN_FLD_AMOUNT, 1, ebufp); cmdp = (pin_charge_cmd_t *)PIN_FLIST_FLD_GET(flistp, PIN_FLD_COMMAND, 0, ebufp); a_pdp = (poid_t *)PIN_FLIST_FLD_GET(flistp, PIN_FLD_ACCOUNT_OBJ,0,ebufp); selectp = (int *)PIN_FLIST_FLD_GET(flistp, PIN_FLD_SELECT_RESULT, 1, ebufp); /*************************************************** * Did PCM_OP_PYMT_SELECT_ITEMS retured OK? ***************************************************/ if (selectp && (*selectp != PIN_SELECT_RESULT_PASS)){ result = PIN_CHARGE_RES_FAIL_SELECT_ITEMS; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Select Items Failed"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); continue; } /*************************************************** * Get the amount for this charge. If the amount to * be charged is 0.0, then don't even bother dealing * with this element. ***************************************************/ if ((amtp && pbo_decimal_compare(amtp, minimum_pay, ebufp) < 0) && (cmdp && ((*cmdp == PIN_CHARGE_CMD_CONDITION) || (*cmdp == PIN_CHARGE_CMD_AUTH_ONLY) || (*cmdp == PIN_CHARGE_CMD_DEPOSIT)))) { result = PIN_CHARGE_RES_FAIL_NO_MIN; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Below Minimum"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); continue; } /*************************************************** * Set the minimum refund to compare. ***************************************************/ if (cmdp && ((*cmdp == PIN_CHARGE_CMD_NONE) && (pbo_decimal_sign(amtp, ebufp) < 0))) { pbo_decimal_negate_assign(minimum_ref, ebufp); } /*************************************************** * If command and amount are not NULL and if the * command is refund or if the commnd is none, but * has a negative amount, check the amount with * the minimum refund. ***************************************************/ if (cmdp && amtp && (((*cmdp == PIN_CHARGE_CMD_REFUND) && (pbo_decimal_compare(amtp, minimum_ref, ebufp) < 0)) || ((*cmdp == PIN_CHARGE_CMD_NONE) && (pbo_decimal_sign(amtp, ebufp) < 0) && (pbo_decimal_compare(amtp, minimum_ref, ebufp) > 0)))) { result = PIN_CHARGE_RES_FAIL_NO_MIN; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Below Minimum"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); continue; } /*************************************************** * If command and amount are not NULL and if the * command is REFUND or if the command is NONE and * its a negative amount, make sure that the account * has sufficient credit balance. If not, set the * RESULT code to be NO_CREDIT_BALANCE. ***************************************************/ if (cmdp && amtp && ((*cmdp == PIN_CHARGE_CMD_REFUND) || ((*cmdp == PIN_CHARGE_CMD_NONE) && (pbo_decimal_sign(amtp, ebufp) < 0)))) { flag = fm_pymt_pol_pre_collect_validate_refund(ctxp, amtp, flistp, ebufp); if (flag == PIN_BOOLEAN_FALSE) { result = PIN_CHARGE_RES_NO_CREDIT_BALANCE; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "No credit available"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); } } /*************************************************** * Is there a outstanding checkpoint for this acct? ***************************************************/ if ((chkpt_flistp != (pin_flist_t *)NULL) && cmdp && ((*cmdp == PIN_CHARGE_CMD_CONDITION) || (*cmdp == PIN_CHARGE_CMD_REFUND) || (*cmdp == PIN_CHARGE_CMD_AUTH_ONLY) || (*cmdp == PIN_CHARGE_CMD_DEPOSIT))) { if (fm_pymt_pol_is_chkpt_outstanding(a_pdp, chkpt_flistp, ebufp)) { result = PIN_CHARGE_RES_CHECKPOINT; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Checkpoint Outstanding"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); continue; } } s_flistp = PIN_FLIST_CREATE(ebufp); vp = PIN_FLIST_FLD_GET(flistp, PIN_FLD_ACH, 1, ebufp); if (vp) { vp = PIN_FLIST_FLD_GET(in_flistp, PIN_FLD_POID, 0, ebufp); PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_POID, vp, ebufp); vp = PIN_FLIST_FLD_GET(flistp, PIN_FLD_ACH, 0, ebufp); if (vp) { rec_id = *(int32 *)vp; } PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_ACH, &rec_id, ebufp); PCM_OP(ctxp, PCM_OP_PYMT_GET_ACH_INFO, sflag, s_flistp, &r_flistp, ebufp); rc_flistp = PIN_FLIST_ELEM_GET(r_flistp, PIN_FLD_RESULTS, 0, 0, ebufp); vp = PIN_FLIST_FLD_GET(rc_flistp, PIN_FLD_NAME, 0, ebufp); memset(vendor_name, 0, sizeof(vendor_name)); if ((vp != (void *)NULL) && strlen(vp)) { strcpy(vendor_name, (char *)vp); } } PIN_FLIST_DESTROY_EX(&s_flistp, NULL); PIN_FLIST_DESTROY_EX(&r_flistp, NULL); /************************************************************* * If Bertelsmann then check the mandate status. *************************************************************/ if (dd_vendorp && !strcasecmp(dd_vendorp, "Bertelsmann") && cmdp && *cmdp != PIN_CHARGE_CMD_RFR && vendor_name && !strcasecmp(vendor_name, "bertelsmann")) { s_flistp = PIN_FLIST_CREATE(ebufp); s_pdp = PIN_POID_CREATE(PIN_POID_GET_DB(a_pdp), "/search/pin", 0, ebufp); PIN_FLIST_FLD_PUT(s_flistp, PIN_FLD_POID, (void *)s_pdp, ebufp); PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_FLAGS, (void *)&sflag, ebufp); PIN_FLIST_FLD_SET(s_flistp, PIN_FLD_TEMPLATE, "select X from /payinfo where F1 = V1 ", ebufp); a_flistp = PIN_FLIST_ELEM_ADD(s_flistp, PIN_FLD_ARGS, 1, ebufp); PIN_FLIST_FLD_SET(a_flistp, PIN_FLD_ACCOUNT_OBJ, a_pdp, ebufp); a_flistp = PIN_FLIST_ELEM_ADD(s_flistp, PIN_FLD_RESULTS, 0, ebufp); b_flistp = PIN_FLIST_ELEM_ADD(a_flistp, PIN_FLD_DD_INFO, 0, ebufp); PIN_FLIST_FLD_SET(b_flistp, PIN_FLD_MANDATE_STATUS, (void *)0, ebufp); PCM_OP(ctxp, PCM_OP_SEARCH, 0, s_flistp, &r_flistp, ebufp); if (r_flistp != (pin_flist_t *)NULL) { a_flistp = PIN_FLIST_ELEM_GET(r_flistp, PIN_FLD_RESULTS, 0, 1, ebufp); b_flistp = PIN_FLIST_ELEM_GET(a_flistp, PIN_FLD_DD_INFO, 0, 1, ebufp); /*********************************************** * Do not allow accounts with the following * mandate_statuses to go to collection. ***********************************************/ mandate_status = PIN_FLIST_FLD_GET(b_flistp, PIN_FLD_MANDATE_STATUS, 1, ebufp); if (!mandate_status || ((*mandate_status != PIN_MANDATE_RECEIVED) && (*mandate_status != PIN_MANDATE_NOT_REQUIRED))) { result = PIN_CHARGE_RES_FAIL_SELECT_ITEMS; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Mandate Outstanding"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); } } /*********************************************** * Clean up. ***********************************************/ PIN_FLIST_DESTROY_EX(&s_flistp, NULL); PIN_FLIST_DESTROY_EX(&r_flistp, NULL); } /*************************************************** * Check the command for this element. ***************************************************/ if (cmdp == NULL) { pin_set_err(ebufp, PIN_ERRLOC_FM, PIN_ERRCLASS_APPLICATION, PIN_ERR_MISSING_ARG, PIN_FLD_COMMAND, elemid, 0); continue; } /*************************************************** * Is it ok? ***************************************************/ switch (*cmdp) { case PIN_CHARGE_CMD_NONE: case PIN_CHARGE_CMD_AUTH_ONLY: case PIN_CHARGE_CMD_CONDITION: case PIN_CHARGE_CMD_DEPOSIT: case PIN_CHARGE_CMD_REFUND: case PIN_CHARGE_CMD_RFR: case PIN_CHARGE_CMD_RESUBMIT: break; default: result = PIN_CHARGE_RES_INVALID_CMD; PIN_FLIST_FLD_SET(flistp, PIN_FLD_RESULT, (void *)&result, ebufp); descr = "Invalid Command"; PIN_FLIST_FLD_SET(flistp, PIN_FLD_DESCR, (void *)descr, ebufp); } } /*********************************************************** * Clean up. ***********************************************************/ PIN_FLIST_DESTROY_EX(&chkpt_flistp, NULL); pbo_decimal_destroy(&minimum_pay); pbo_decimal_destroy(&minimum_ref); if (dd_vendorp != (char *)NULL) { free(dd_vendorp); dd_vendorp = NULL; } /*********************************************************** * Results. ***********************************************************/ if (PIN_ERR_IS_ERR(ebufp)) { PIN_FLIST_DESTROY_EX(&c_flistp, NULL); PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "op_pymt_pol_pre_collect error", ebufp); } else { *ret_flistpp = c_flistp; PIN_ERR_CLEAR_ERR(ebufp); PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "op_pymt_pol_pre_collect return flist", *ret_flistpp); } return; }
/******************************************************************* * fm_zonemap_pol_get_lineage_load_zonemap(): * * Retrieve and process the named zonemap. * *******************************************************************/ static int32 fm_zonemap_pol_get_lineage_load_zonemap( pcm_context_t *pCtx, const char *pszTarget, poid_t *pRoutingPoid, poid_t **ppZonemapPoid, poid_t *pBrandPoid, Blob_t **ppBuffer, int32 *pnDefaultSearchMode, pin_errbuf_t *ebufp) { pin_flist_t *pGetZonemapInFlist = NULL; pin_flist_t *pGetZonemapOutFlist = NULL; pin_flist_t *pZonemaps = NULL; poid_t *pSearchPoid = NULL; pin_buf_t *pBuf = NULL; Blob_t *pTempBufAddr = NULL; int32 nRetVal = PIN_BOOLEAN_TRUE; pin_zonemap_data_type_t dt = PIN_ZONEMAP_DATA_BINARY; int32 *pnSearchMode; PIN_HEAP_VAR; /* Debug */ PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_load_zonemap starting"); /* * Create flist for retrieving matrix */ pGetZonemapInFlist = PIN_FLIST_CREATE(ebufp); pSearchPoid = PIN_POID_CREATE(PIN_POID_GET_DB((poid_t *) pRoutingPoid), "/zonemap", -1, ebufp); PIN_FLIST_FLD_PUT(pGetZonemapInFlist, PIN_FLD_POID, (void *)pSearchPoid, ebufp); PIN_FLIST_FLD_SET(pGetZonemapInFlist, PIN_FLD_NAME, (void *) pszTarget, ebufp); PIN_FLIST_FLD_SET(pGetZonemapInFlist, PIN_FLD_ZONEMAP_DATA_TYPE, (void *) &dt, ebufp); PIN_FLIST_FLD_SET(pGetZonemapInFlist, PIN_FLD_ACCOUNT_OBJ, (void *) pBrandPoid, ebufp); /* * Call zonemap loading opcode (automatically seaches) */ PCM_OP(pCtx, PCM_OP_ZONEMAP_GET_ZONEMAP, 0, pGetZonemapInFlist, &pGetZonemapOutFlist, ebufp); /* * Process matrix */ pZonemaps = PIN_FLIST_ELEM_GET(pGetZonemapOutFlist, PIN_FLD_ZONEMAPS, PIN_ELEMID_ANY, 1, ebufp); if (pZonemaps != NULL) { /* * Found a zonemap, set current matrix poid */ PIN_SET_GLOBAL_HEAP; *ppZonemapPoid = PIN_POID_COPY((poid_t*) PIN_FLIST_FLD_GET(pZonemaps,PIN_FLD_POID, 0, ebufp), ebufp); PIN_RESET_GLOBAL_HEAP; /* * Grab default search mode (NULL means no default) */ pnSearchMode = (int32*) PIN_FLIST_FLD_GET(pZonemaps, PIN_FLD_ZONEMAP_SEARCH_TYPE, 1, ebufp); /* Did we find a default search mode? */ if (pnSearchMode != NULL) { /* Yes: copy value to input */ *pnDefaultSearchMode = *pnSearchMode; } else { /* No: indicate no default search mode */ pnDefaultSearchMode = NULL; } /* * Get address of buffer */ pBuf = (pin_buf_t *)PIN_FLIST_FLD_GET(pZonemaps, PIN_FLD_ZONEMAP_DATA_DERIVED, 1, ebufp); if (pBuf != NULL && (pBuf->data != NULL)) { /* get the actual blob */ pTempBufAddr = (Blob_t *)(pBuf->data); PIN_SET_GLOBAL_HEAP; /* Allocate memory to hold buffer on global heap */ *ppBuffer = (Blob_t*) malloc(pTempBufAddr->blob_size); /* Copy buffer to global mem */ memcpy(*ppBuffer, pTempBufAddr, pTempBufAddr->blob_size); PIN_RESET_GLOBAL_HEAP; } else { *ppBuffer = NULL; PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_WARNING, "fm_zonemap_pol_get_lineage_load_zonemap: " "zonemap is empty!", ebufp); } } else { /* * No zonemap found */ nRetVal = PIN_BOOLEAN_FALSE; } /* * Clean up */ PIN_FLIST_DESTROY_EX(&pGetZonemapInFlist, NULL); PIN_FLIST_DESTROY_EX(&pGetZonemapOutFlist, NULL); if (PIN_ERR_IS_ERR(ebufp)) { nRetVal = PIN_BOOLEAN_FALSE; if (ebufp->pin_err == PIN_ERR_NO_MATCH) { PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_load_zonemap: " "no matrix"); PIN_ERR_CLEAR_ERR(ebufp); } else { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_zonemap_pol_get_lineage_load_zonemap: error", ebufp); } } /* Debug */ PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_load_zonemap returning"); return nRetVal; }
/******************************************************************* * fm_zonemap_pol_get_lineage_rev_changed(): * * Determine whether the matrix has changed since we loaded it. * *******************************************************************/ static int32 fm_zonemap_pol_get_lineage_rev_changed( pcm_context_t *pCtx, const poid_t *pMatrixPoid, pin_errbuf_t *ebufp) { pin_flist_t *pReadPoidInFlist = NULL; pin_flist_t *pReadPoidOutFlist = NULL; poid_t *pNewPoid = NULL; int32 nRetVal; int64 in_db_no; /* Sanity check */ if (PIN_ERR_IS_ERR(ebufp)) { return PIN_BOOLEAN_FALSE; } /* Debug */ PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_rev_changed starting"); /* * Create flist for reading the zonemap poid */ pReadPoidInFlist = PIN_FLIST_CREATE(ebufp); /* In multi-db case the input context DB number may be different than the one earlier cached in pMatrixPoid. * So do READ_FLDS on the DB from input context for cached zonemap poid to avoid error from CM that * a transaction is already open. */ pNewPoid = PIN_POID_COPY((poid_t *)pMatrixPoid, ebufp); in_db_no = cm_fm_get_current_db_no(pCtx); PIN_POID_SET_DB(pNewPoid, in_db_no); PIN_FLIST_FLD_PUT(pReadPoidInFlist, PIN_FLD_POID, pNewPoid, ebufp); PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_rev_changed zonemap read_flds input flist", pReadPoidInFlist); /* * Read current poid from DB */ PCM_OP(pCtx, PCM_OP_READ_FLDS, 0, pReadPoidInFlist, &pReadPoidOutFlist, ebufp); PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_rev_changed zonemap read_flds output flist", pReadPoidOutFlist); /* * Compare poid revs */ /* Get new poid from flist */ pNewPoid = (poid_t*) PIN_FLIST_FLD_GET(pReadPoidOutFlist, PIN_FLD_POID, 0, ebufp); /* To compare poids for revision check and in multi-db case just set back the * pMatrixPoid cached zonemap poid DB number to the newly read poid * to just compare poid_id, type and revision and not db number */ in_db_no = PIN_POID_GET_DB((poid_t *)pMatrixPoid); PIN_POID_SET_DB(pNewPoid, in_db_no); /* Is db rev newer than stored rev? */ if (PIN_POID_COMPARE(pNewPoid, (poid_t*)pMatrixPoid, PIN_BOOLEAN_TRUE, ebufp)) { /* Yes: set return to true */ nRetVal = PIN_BOOLEAN_TRUE; } else { /* No: set return to false */ nRetVal = PIN_BOOLEAN_FALSE; } /* * Clean up */ PIN_FLIST_DESTROY_EX(&pReadPoidInFlist, NULL); PIN_FLIST_DESTROY_EX(&pReadPoidOutFlist, NULL); if (PIN_ERR_IS_ERR(ebufp)) { PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "fm_zonemap_pol_get_lineage_rev_changed() error", ebufp); /* Set return value to error */ nRetVal = PIN_BOOLEAN_FALSE; } /* Debug */ PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "fm_zonemap_pol_get_lineage_rev_changed returning"); return nRetVal; }