]> git.evergreen-ils.org Git - contrib/Conifer.git/blob - Open-ILS/src/sql/Pg/upgrade/XXXX.generate_patron_barcodes.sql
Generic patron barcode generation (OpenSRF and DB)
[contrib/Conifer.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.generate_patron_barcodes.sql
1 -- Provides support for generating patron barcodes, with optional prefixes
2 -- If all digits, then a mod10 check digit is calculated and appended
3 CREATE SEQUENCE evergreen.actor_barcode_seq;
4
5 CREATE OR REPLACE FUNCTION evergreen.mod10(barcode TEXT)
6 RETURNS TEXT AS $$
7 use strict; 
8 use warnings; 
9  
10 my $barcode = shift; 
11 my $total = 0; 
12 my $position = 0; 
13 foreach my $digit (split('', $barcode)) { 
14     $digit = sprintf('%d', $digit); 
15     $position++; 
16     if ($position % 2) { 
17         # Double it 
18         $digit *= 2; 
19         # If less than 10, add to the total 
20         if ($digit < 10) { 
21             $total += $digit; 
22         } else { 
23             $total += $digit - 9; 
24         } 
25     } else { 
26         $total += $digit; 
27     } 
28
29 my $rem = $total % 10; 
30 if ($rem) { 
31     return 10 - $rem; 
32
33 return $rem;  
34 $$ LANGUAGE plperlu;
35
36 CREATE OR REPLACE FUNCTION evergreen.actor_generate_barcode(prefix TEXT DEFAULT 'AUTOBC')
37 RETURNS TEXT AS $$
38 DECLARE 
39     bc_gen TEXT; 
40     mod TEXT; 
41     bc_serial RECORD; 
42     bc_holder TEXT; 
43 BEGIN 
44     LOOP 
45         SELECT lpad(NEXTVAL('evergreen.actor_barcode_seq')::text, 7, '0') AS bc INTO bc_serial; 
46         bc_gen := rpad(COALESCE(prefix, '0'), 6, '0') || bc_serial.bc::text; 
47         IF unnest(regexp_matches(bc_gen, '\D')) IS NOT NULL THEN
48             bc_gen := rpad(bc_gen, 14, '0');
49         ELSE
50             bc_gen := bc_gen || evergreen.mod10(bc_gen); 
51         END IF;
52  
53         SELECT barcode INTO bc_holder FROM actor.card WHERE barcode = bc_gen; 
54         EXIT WHEN bc_holder IS NULL; 
55     END LOOP; 
56  
57     RETURN bc_gen; 
58 END;  
59 $$ LANGUAGE plpgsql;
60
61 CREATE OR REPLACE FUNCTION evergreen.actor_update_barcode(usr_id INT, prefix TEXT DEFAULT NULL)
62 RETURNS TEXT AS $$
63 DECLARE
64     bc_gen TEXT;
65     bc_holder TEXT;
66 BEGIN
67
68     LOOP
69         IF prefix IS NULL THEN
70             bc_gen := evergreen.actor_generate_barcode();
71         ELSE
72             bc_gen := evergreen.actor_generate_barcode(prefix);
73         END IF;
74
75         SELECT barcode INTO bc_holder FROM actor.card WHERE barcode = bc_gen;
76         EXIT WHEN bc_holder IS NULL;
77     END LOOP;
78
79     INSERT INTO actor.card (usr, barcode) VALUES (usr_id, bc_gen);
80
81     UPDATE actor.usr
82         SET card = CURRVAL('actor.card_id_seq')
83         WHERE id = usr_id;
84
85     RETURN bc_gen;
86 END;
87 $$ LANGUAGE plpgsql;