/******************************************************************* * 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; }
/******************************************************************* * 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; }
//**************************************************** // createRecourse // Pre: // Post: // void bs_CreateLECRecourse::createRecourse( pin_Session * pinp, const char * sRecordType, const char * sBtn, const char * sAuthDate, const char * sReasonCode, const char * sAmount, const char * sVersion, const char * file_name, pin_flist_t **return_flistpp, pin_errbuf_t *ebufp ) { pin_flist_t * x_flistp = NULL; pin_flist_t * c_flistp = NULL; int lec_db = 5; //WIP: hard coded int command = 9; poid_t * pdp = NULL; pin_decimal_t * amtp = NULL; void * vp = NULL; int impact_type = 0; int version = 0; PIN_ERR_CLEAR_ERR(ebufp); //--enter function-------------- PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_DEBUG, "bs_CreateLECRecourse::createRecourse: enter" ); /*--- Convert ---*/ if (sVersion && strlen(sVersion)> 0 ) version = atoi(sVersion); amtp = pbo_decimal_from_str(sAmount,ebufp); if(amtp && !PIN_ERR_IS_ERR(ebufp) && pbo_decimal_sign(amtp, ebufp) == -1 ) { pbo_decimal_abs_assign(amtp, ebufp); impact_type = 1; } /*--- Create set_status ---*/ x_flistp = PIN_FLIST_CREATE(ebufp); pdp = pin_poid_create((int64)lec_db,"/_lec_db", (int64)1, ebufp); PIN_FLIST_FLD_PUT(x_flistp, PIN_FLD_POID, pdp, ebufp); PIN_FLIST_FLD_SET(x_flistp, PIN_FLD_COMMAND, (void*)&command, ebufp); c_flistp = PIN_FLIST_ELEM_ADD( x_flistp, PIN_FLD_CHARGES, PIN_ELEMID_ASSIGN, ebufp ); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_PHONE, (void*)sBtn, ebufp); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_AUTH_DATE, (void*)sAuthDate, ebufp); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_RECORD_TYPE, (void*)sRecordType, ebufp); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_REASON_CODE, (void*)sReasonCode, ebufp); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_IMPACT_TYPE, (void*)&impact_type, ebufp); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_VERSION_ID, (void*)&version, ebufp); PIN_FLIST_FLD_PUT(c_flistp, PIN_FLD_AMOUNT_ADJUSTED, (void*)amtp, ebufp); if (file_name != NULL ) { c_flistp = PIN_FLIST_ELEM_ADD( x_flistp, PIN_FLD_BATCH_INFO, PIN_ELEMID_ASSIGN, ebufp ); PIN_FLIST_FLD_SET(c_flistp, PIN_FLD_FILENAME, (void*)file_name, ebufp); } /*----* Connect to the LEC DM *---*/ // pcm_context_t *my_ctxp = NULL; // PCM_CONTEXT_OPEN(&my_ctxp, (pin_flist_t *)0, ebufp); PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,"dm search input flist", x_flistp); pinp->call_opcode( PCM_OP_SEARCH, 0, x_flistp, return_flistpp, ebufp); if (return_flistpp) PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG, "dm search output flist", *return_flistpp); // if ( PIN_ERR_IS_ERR(ebufp) ) // { // PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR,"Failed connecting to DM_LEC...", ebufp ); // } // PCM_CONTEXT_CLOSE(my_ctxp, 0, NULL); PIN_ERR_LOG_FLIST(PIN_ERR_LEVEL_DEBUG,(char*)"leaving bs_CreateLECRecourse::createRecourse" , *return_flistpp ); PIN_FLIST_DESTROY_EX(&x_flistp,NULL); return; }