DBA Data[Home] [Help]

PACKAGE BODY: APPS.IBY_CC_VALIDATE

Source


1 PACKAGE BODY IBY_CC_VALIDATE AS
2 /* $Header: ibyccvlb.pls 120.5.12010000.6 2009/06/16 09:53:20 lyanamal ship $ */
3 
4 
5 -- *** Declaring global datatypes and variables ***
6 
7 
8   FUNCTION CheckCCDigits( p_cc_id  IN VARCHAR2 ) RETURN NUMBER
9   AS
10 
11 	v_DigitSum	INTEGER		:=0;
12 	v_CCDigit	INTEGER		:=0;
13 	v_CCLen		INTEGER		:=0;
14   BEGIN
15 	v_CCLen:=LENGTH(p_cc_id);
16 
17 	FOR v_Counter IN 1..v_CCLen LOOP
18 
19 	  v_CCDigit := TO_NUMBER(SUBSTR(p_cc_id,v_CCLen-v_Counter+1,1));
20 
21 	  -- every alternate digit beginning with the second one from the
22 	  -- right must be doubled and the resultant digits added together
23 	  --
24 	  IF MOD(v_Counter,2)=0 THEN
25 		--
26 		-- according to the algorithm, resulting digits must be
27 		-- added together; only an issue for #'s >=5
28 		IF v_CCDigit<5 THEN
29 		  v_CCDigit := v_CCDigit*2;
30 		ELSE
31 		  -- this function just happens to fit the algorithm
32 		  -- "double x and then add its digits together" for
33 		  -- all x >=5 and <=9
34 		  --
35 		  v_CCDigit := 1+2*(v_CCDigit-5);
36 		END IF;
37 	  END IF;
38 	  --DBMS_OUTPUT.PUT_LINE('digit value is : ' || v_CCDigit);
39 	  v_DigitSum := v_DigitSum + v_CCDigit;
40 
41 	END LOOP;
42 
43 	--DBMS_OUTPUT.PUT_LINE('digit sum is : ' || v_DigitSum);
44 
45 	RETURN MOD(v_DigitSum,10);
46 
47   EXCEPTION
48 --	WHEN VALUE_ERROR THEN
49 	WHEN OTHERS THEN
50 		RETURN NULL;
51   END CheckCCDigits;
52 
53 /*
54 ** This function returns the CC Type in String for the CC Type in
55 ** number passed. It maps the constant defined for CC Type in this
56 ** Package to ones in the LOOKUP Types for the type 'IBY_CARD_TYPES'.
57 */
58 
59     FUNCTION getLookupCCType( p_cc_type IN NUMBER )
60     RETURN VARCHAR2
61     AS
62 
63     BEGIN
64 
65        IF( p_cc_type = 0 ) THEN
66           RETURN 'UNKNOWN';
67        ELSIF( p_cc_type = 1 ) THEN
68           RETURN 'MASTERCARD';
69        ELSIF( p_cc_type = 2 ) THEN
70           RETURN 'VISA';
71        ELSIF( p_cc_type = 3 ) THEN
72           RETURN 'AMEX';
73        ELSIF( p_cc_type = 4 ) THEN
74           RETURN 'DINERS';
75        ELSIF( p_cc_type = 5 ) THEN
76           RETURN 'DISCOVER';
77        ELSIF( p_cc_type = 6 ) THEN
78           RETURN 'ENROUTE';
79        ELSIF( p_cc_type = 7 ) THEN
80           RETURN 'JCB';
81        ELSE
82           RETURN NULL;
83        END IF;
84 
85     EXCEPTION
86         WHEN OTHERS THEN
87                 RETURN NULL;
88     END getLookupCCType;
89 
90 
91     FUNCTION getIssuerCCType( p_cc_issuer IN VARCHAR2 )
92     RETURN VARCHAR2
93     AS
94 
95     BEGIN
96 
97        IF( p_cc_issuer = 'UNKNOWN' ) THEN
98           RETURN 0;
99        ELSIF( p_cc_issuer = 'INVALID' ) THEN
100           RETURN c_InvalidCC;
101        ELSIF( p_cc_issuer = 'MASTERCARD' ) THEN
102           RETURN 1;
103        ELSIF( p_cc_issuer = 'VISA' ) THEN
104           RETURN 2;
105        ELSIF( p_cc_issuer = 'AMEX' ) THEN
106           RETURN 3;
107        ELSIF( p_cc_issuer = 'DINERS' ) THEN
108           RETURN 4;
109        ELSIF( p_cc_issuer = 'DISCOVER' ) THEN
110           RETURN 5;
111        ELSIF( p_cc_issuer = 'ENROUTE' ) THEN
112           RETURN 6;
113        ELSIF( p_cc_issuer = 'JCB' ) THEN
114           RETURN 7;
115        ELSE
116           RETURN NULL;
117        END IF;
118 
119     END getIssuerCCType;
120 
121   PROCEDURE StripCC (	p_api_version		IN	NUMBER,
122 			p_init_msg_list		IN	VARCHAR2,
123 			p_cc_id 		IN 	VARCHAR2,
124 			p_fill_chars		IN	VARCHAR2,
125 
126 			x_return_status		OUT NOCOPY VARCHAR2,
127 			x_msg_count		OUT NOCOPY NUMBER,
128 			x_msg_data		OUT NOCOPY VARCHAR2,
129 			x_cc_id 		OUT NOCOPY VARCHAR2
130 			)	AS
131 
132 	c_Digits	CONSTANT VARCHAR2(10) 	:='0123456789';
133 	v_StrippedCC	VARCHAR2(100)		:='';
134 	v_CCChar	CHAR;
135 	v_FoundBadChar	BOOLEAN			:=FALSE;
136   BEGIN
137 	FOR v_Counter IN 1..LENGTH(p_cc_id) LOOP
138 	  --
139 	  -- tests if a character is a digit
140 	  --
141 	  v_CCChar := SUBSTR(p_cc_id,v_Counter,1);
142 
143 	  IF INSTR(c_Digits,v_CCChar)>0 THEN
144 		v_StrippedCC := v_StrippedCC || v_CCChar;
145 	  ELSIF INSTR(p_fill_chars,v_CCChar)>0 THEN
146 		NULL;
147 	  ELSE
148 		-- an illegal character found in the string
149 		--
150 		v_FoundBadChar:=TRUE;
151 		--DBMS_OUTPUT.PUT_LINE('bad char: ' || v_CCChar);
152 		EXIT;
153 	  END IF;
154 	END LOOP;
155 
156 	IF v_FoundBadChar THEN
157 	  -- !!
158 	  -- do something useful here!!
159 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
160 	  x_cc_id := NULL;
161 	ELSE
162 	  x_return_status := FND_API.G_RET_STS_SUCCESS;
163 	  x_cc_id := v_StrippedCC;
164 	END IF;
165 
166 	--DBMS_OUTPUT.PUT_LINE('stripped value is: ' || v_StrippedCC);
167 
168   EXCEPTION
169 	WHEN OTHERS THEN
170 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
171 	  x_cc_id := NULL;
172   END StripCC;
173 
174   PROCEDURE StripCC (	p_api_version		IN	NUMBER,
175 			p_init_msg_list		IN	VARCHAR2,
176 			p_cc_id 		IN 	VARCHAR2,
177 
178 			x_return_status		OUT NOCOPY VARCHAR2,
179 			x_msg_count		OUT NOCOPY NUMBER,
180 			x_msg_data		OUT NOCOPY VARCHAR2,
181 			x_cc_id 		OUT NOCOPY VARCHAR2
182 			)	AS
183 
184   BEGIN
185 
186 	StripCC(p_api_version, p_init_msg_list, p_cc_id,
187 		c_FillerChars, x_return_status, x_msg_count,
188 		x_msg_data, x_cc_id );
189 
190   END StripCC;
191 
192   FUNCTION StripCC ( p_cc_id IN VARCHAR2, p_fill_chars IN VARCHAR2 )
193   RETURN VARCHAR2
194   IS
195     c_Digits        CONSTANT VARCHAR2(10) :='0123456789';
196     v_StrippedCC    VARCHAR2(100) := '';
197     v_CCChar        CHAR;
198     v_FoundBadChar  BOOLEAN :=FALSE;
199     l_DBUG_MOD         VARCHAR2(100) :='IBY_CC_VALIDATE.Get_CC_Issuer_Range(6 params)';
200   BEGIN
201 
202     iby_debug_pub.add('Enter',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
203 
204 	FOR v_Counter IN 1..LENGTH(p_cc_id) LOOP
205 	  --
206 	  -- tests if a character is a digit
207 	  --
208 	  v_CCChar := SUBSTR(p_cc_id,v_Counter,1);
209 
210 
211 	  IF INSTR(c_Digits,v_CCChar)>0 THEN
212 		v_StrippedCC := v_StrippedCC || v_CCChar;
213 	  ELSIF INSTR(p_fill_chars,v_CCChar)>0 THEN
214 		NULL;
215 	  ELSE
216 		v_FoundBadChar:=TRUE;
217 		EXIT;
218 	  END IF;
219 	END LOOP;
220 
221 	IF v_FoundBadChar THEN
222          iby_debug_pub.add('Found bad char',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
223 
224           RETURN NULL;
225 	ELSE
226 	 RETURN v_StrippedCC;
227 	END IF;
228     iby_debug_pub.add('Exit',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
229 
230 
231     EXCEPTION
232     WHEN OTHERS THEN
233       iby_debug_pub.add('In Others Exception',FND_LOG.LEVEL_UNEXPECTED, l_DBUG_MOD);
234       iby_debug_pub.add('Exception code='||SQLCODE,FND_LOG.LEVEL_UNEXPECTED,l_DBUG_MOD);
235       iby_debug_pub.add('Exception message='||SQLERRM,FND_LOG.LEVEL_UNEXPECTED,l_DBUG_MOD);
236 
237 
238   END StripCC;
239 
240 
241   PROCEDURE GetCCType (	p_api_version		IN	NUMBER,
242 			p_init_msg_list		IN	VARCHAR2,
243 			p_cc_id 		IN 	VARCHAR2,
244 
245 			x_return_status		OUT NOCOPY VARCHAR2,
246 			x_msg_count		OUT NOCOPY NUMBER,
247 			x_msg_data		OUT NOCOPY VARCHAR2,
248 			x_cc_type 		OUT NOCOPY CCType
249 			)	AS
250 
251 	v_Length        INTEGER;
252 	v_DigitsOk	BOOLEAN;
253         lx_card_issuer  iby_creditcard_issuers_b.card_issuer_code%TYPE;
254         lx_range_id     iby_cc_issuer_ranges.cc_issuer_range_id%TYPE;
255         lx_card_prefix  iby_cc_issuer_ranges.card_number_prefix%TYPE;
256         lx_digit_check  iby_creditcard_issuers_b.digit_check_flag%TYPE;
257 
258   BEGIN
259 	x_return_status := FND_API.G_RET_STS_SUCCESS;
260 
261 	IF (p_cc_id IS NULL) THEN
262 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
263 	  x_cc_type:=c_InvalidCC;
264 	  RETURN;
265 	END IF;
266 
267 	v_Length:=LENGTH(p_cc_id);
268 
269 	IF (v_Length <=0) THEN
270 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
271 	  x_cc_type:=c_InvalidCC;
272 	  RETURN;
273 	END IF;
274 
275         Get_CC_Issuer_Range
276         (p_cc_id,lx_card_issuer,lx_range_id,lx_card_prefix,lx_digit_check);
277 
278         IF (lx_digit_check = 'Y') THEN
279           v_DigitsOk:= CheckCCDigits(p_cc_id) = 0;
280         ELSE
281           v_DigitsOk:= TRUE;
282         END IF;
283 
284 	-- this means there were some non-digit characters
285 	-- in the credit card number
286 	--
287 	IF StripCC(p_cc_id,c_FillerChars) IS NULL THEN
288 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
289 	  x_cc_type:=c_InvalidCC;
290 	  RETURN;
291 	END IF;
292 
293         IF NOT v_DigitsOk THEN
294 	  x_cc_type:=c_InvalidCC;
295         ELSE
296           x_cc_type := getIssuerCCType(NVL(lx_card_issuer,'UNKNOWN'));
297 	END IF;
298 
299   EXCEPTION
300 	WHEN OTHERS THEN
301 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
302 	  x_cc_type:=c_InvalidCC;
303   END GetCCType;
304 
305 
306 /*
307 ** This is an overloaded function which returns, a boolean value -
308 ** indicating whether the card is valid or not, AND CC type (in VARCHAR2)
309 ** from the lookup types defined for type 'IBY_CARD_TYPES'
310 */
311 
312   PROCEDURE ValidateCC (p_api_version		IN	NUMBER,
313 			p_init_msg_list		IN	VARCHAR2,
314 			p_cc_id 		IN 	VARCHAR2,
315 			p_expr_date		IN	DATE,
316 
317 			x_return_status		OUT NOCOPY VARCHAR2,
318 			x_msg_count		OUT NOCOPY NUMBER,
319 			x_msg_data		OUT NOCOPY VARCHAR2,
320 			x_cc_valid 		OUT NOCOPY BOOLEAN,
321 			x_cc_type               OUT NOCOPY VARCHAR2
322 			)	AS
323 
324 	v_CurrDate	DATE	:= SYSDATE();
325 	v_CardType	CCType;
326 	v_spread	REAL;
327   BEGIN
328 
329 	-- expr date is moved to the last day of the month it's on as
330 	-- most credit cards
331 	--
332 	v_spread:=MONTHS_BETWEEN(LAST_DAY(TRUNC(p_expr_date)),
333 		TRUNC(v_CurrDate));
334 	x_return_status := FND_API.G_RET_STS_SUCCESS;
335 
336 	--DBMS_OUTPUT.PUT_LINE('Difference in time: ' || v_spread);
337 	IF v_spread >= 0 THEN
338 
339 		GetCCType(p_api_version, p_init_msg_list, p_cc_id,
340 			x_return_status, x_msg_count, x_msg_data,
341 			v_CardType );
342 		x_cc_valid:=(v_CardType<>c_InvalidCC);
343                 x_cc_type := getLookupCCType( v_CardType );
344 
345 		/* set the other out variables here */
346 	ELSE
347 
348 		x_cc_valid:=FALSE;
349 
350 		/* set the other out variables here */
351 	END IF;
352 
353   EXCEPTION
354 	WHEN OTHERS THEN
355 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
356 	  x_cc_valid:=FALSE;
357   END ValidateCC;
358 
359 
360 /*
361 ** This is an overloaded function which returns, a boolean value -
362 ** indicating whether the card is valid or not.
363 */
364 
365   PROCEDURE ValidateCC (p_api_version		IN	NUMBER,
366 			p_init_msg_list		IN	VARCHAR2,
367 			p_cc_id 		IN 	VARCHAR2,
368 			p_expr_date		IN	DATE,
369 
370 			x_return_status		OUT NOCOPY VARCHAR2,
371 			x_msg_count		OUT NOCOPY NUMBER,
372 			x_msg_data		OUT NOCOPY VARCHAR2,
373 			x_cc_valid 		OUT NOCOPY BOOLEAN
374 			)	AS
375 
376         v_CC_Type       VARCHAR2(80);
377 
378   BEGIN
379 
380             ValidateCC (p_api_version       =>          p_api_version,
381                         p_init_msg_list     =>          p_init_msg_list,
382                         p_cc_id             =>          p_cc_id,
383                         p_expr_date         =>          p_expr_date,
384                         x_return_status     =>          x_return_status,
385                         x_msg_count         =>          x_msg_count,
386                         x_msg_data          =>          x_msg_data,
387                         x_cc_valid          =>          x_cc_valid,
388                         x_cc_type           =>          v_CC_Type
389                         );
390 
391   EXCEPTION
392 	WHEN OTHERS THEN
393 	  x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
394 	  x_cc_valid:=FALSE;
395 
396   END ValidateCC;
397 
398   PROCEDURE Get_CC_Issuer_Range
399   (p_card_number     IN     iby_creditcard.ccnumber%TYPE,
400    x_card_issuer     OUT NOCOPY iby_creditcard_issuers_b.card_issuer_code%TYPE,
401    x_issuer_range    OUT NOCOPY iby_cc_issuer_ranges.cc_issuer_range_id%TYPE,
402    x_card_prefix     OUT NOCOPY iby_cc_issuer_ranges.card_number_prefix%TYPE,
403    x_digit_check     OUT NOCOPY iby_creditcard_issuers_b.digit_check_flag%TYPE
404   )
405   IS
406     l_cc_number        iby_creditcard.ccnumber%TYPE;
407     l_length           NUMBER;
408     l_DBUG_MOD         VARCHAR2(100) :='IBY_CC_VALIDATE.Get_CC_Issuer_Range(5 params)';
409 
410   BEGIN
411 
412     iby_debug_pub.add('Enter',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
413 
414     iby_debug_pub.add('Calling  Get_CC_Issuer_Range (6 params)',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
415 
416     Get_CC_Issuer_Range(p_card_number,x_card_issuer,x_issuer_range,x_card_prefix,x_digit_check,null);
417 
418      iby_debug_pub.add('Exit',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
419 
420   END Get_CC_Issuer_Range;
421 --Bug 8581161: FP:8352320
422 PROCEDURE Get_CC_Issuer_Range
423   (p_card_number     IN     iby_creditcard.ccnumber%TYPE,
424    x_card_issuer     OUT NOCOPY iby_creditcard_issuers_b.card_issuer_code%TYPE,
425    x_issuer_range    OUT NOCOPY iby_cc_issuer_ranges.cc_issuer_range_id%TYPE,
426    x_card_prefix     OUT NOCOPY iby_cc_issuer_ranges.card_number_prefix%TYPE,
427    x_digit_check     OUT NOCOPY iby_creditcard_issuers_b.digit_check_flag%TYPE,
428    p_card_type       IN iby_creditcard.card_issuer_code%TYPE
429   )
430   IS
431     l_cc_number        iby_creditcard.ccnumber%TYPE;
432     l_length           NUMBER;
433     l_DBUG_MOD         VARCHAR2(100) :='IBY_CC_VALIDATE.Get_CC_Issuer_Range(6 params)';
434 
435     CURSOR c_range
436     (ci_card_number IN iby_creditcard.ccnumber%TYPE,
437      ci_card_len IN NUMBER,
438      ci_card_type IN iby_creditcard.card_issuer_code%TYPE)
439     IS
440       SELECT cc_issuer_range_id, r.card_issuer_code,
441         card_number_prefix, NVL(digit_check_flag,'N')
442       FROM iby_cc_issuer_ranges r, iby_creditcard_issuers_b i
443       WHERE (card_number_length = ci_card_len)
444         AND (INSTR(ci_card_number,card_number_prefix) = 1)
445         AND (r.card_issuer_code = i.card_issuer_code)
446 	AND r.card_issuer_code = NVL(ci_card_type, r.card_issuer_code)
447         ORDER BY r.last_updated_by DESC,
448 	  r.last_update_date DESC;
449 
450   BEGIN
451       iby_debug_pub.add('Enter',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
452 
453     IF (c_range%ISOPEN) THEN CLOSE c_range; END IF;
454 
455     l_cc_number :=
456       IBY_CC_VALIDATE.StripCC(p_card_number,IBY_CC_VALIDATE.c_FillerChars);
457 
458     l_length := LENGTH(l_cc_number);
459 
460 
461     IF (l_length > 30) THEN
462       x_card_issuer := 'INVALID';
463     END IF;
464 
465  /*
466 ** Removed all hard coded values.
467 ** We alwasy refer to DB to get the output values.
468 ** Bug# 8581161
469 */
470 
471 
472     OPEN c_range(l_cc_number,l_length,p_card_type);
473     FETCH c_range INTO x_issuer_range, x_card_issuer,
474       x_card_prefix, x_digit_check;
475     CLOSE c_range;
476 
477     IF (x_card_issuer IS NULL) THEN
478       x_card_issuer := 'UNKNOWN';
479       x_digit_check := 'N';
480     END IF;
481 
482        iby_debug_pub.add('Exit',FND_LOG.LEVEL_STATEMENT,l_DBUG_MOD);
483 
484   EXCEPTION
485     WHEN OTHERS THEN
486       iby_debug_pub.add('In Others Exception',FND_LOG.LEVEL_UNEXPECTED, l_DBUG_MOD);
487       iby_debug_pub.add('Exception code='||SQLCODE,FND_LOG.LEVEL_UNEXPECTED,l_DBUG_MOD);
488       iby_debug_pub.add('Exception message='||SQLERRM,FND_LOG.LEVEL_UNEXPECTED,l_DBUG_MOD);
489 
490 
491 
492   END Get_CC_Issuer_Range;
493 
494   FUNCTION Get_CC_Issuer_Range
495   (p_card_number     IN     iby_creditcard.ccnumber%TYPE)
496   RETURN NUMBER
497   IS
498     lx_card_issuer     iby_creditcard_issuers_b.card_issuer_code%TYPE;
499     lx_issuer_range    iby_cc_issuer_ranges.cc_issuer_range_id%TYPE;
500     lx_card_prefix     iby_cc_issuer_ranges.card_number_prefix%TYPE;
501     lx_digit_check     iby_creditcard_issuers_b.digit_check_flag%TYPE;
502   BEGIN
503     Get_CC_Issuer_Range(p_card_number,lx_card_issuer,lx_issuer_range,
504       lx_card_prefix,lx_digit_check);
505     RETURN lx_issuer_range;
506   END Get_CC_Issuer_Range;
507 
508 END IBY_CC_VALIDATE;
509