File Coverage

blib/lib/Lingua/ZH/Currency/UpperCase.pm
Criterion Covered Total %
statement 34 34 100.0
branch 12 12 100.0
condition 4 6 66.6
subroutine 4 4 100.0
pod 1 1 100.0
total 55 57 96.4


line stmt bran cond sub pod time code
1             # $Id$
2             package Lingua::ZH::Currency::UpperCase;
3              
4 1     1   901 use strict;
  1         2  
  1         47  
5 1     1   6 use vars qw( %dig @integer_unit @float_unit $VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         1632  
6              
7             require Exporter;
8              
9             @ISA = qw(Exporter AutoLoader);
10             @EXPORT = qw( chinese_currency_uc );
11             $VERSION = '0.02'; #sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
12              
13             %dig = ( 0 => '零', 1 => '壹', 2 => '贰', 3 => '叁', 4 => '肆',
14             5 => '伍', 6 => '陆', 7 => '柒', 8 => '捌', 9 => '玖' );
15             our @integer_unit = ( '圆','拾','佰','仟','万','拾','佰','仟','亿','拾','佰','仟' );
16             our @float_unit = ( '角','分' );
17              
18             =head1 NAME
19              
20             Lingua::ZH::Currency::UpperCase - Convert Currency Numbers to Chinese UpperCase Format
21              
22             =head1 SYNOPSIS
23              
24             use Lingua::ZH::Currency::UpperCase;
25             print chinese_currency_uc( 2504.39 );
26              
27             =head1 DESCRIPTION
28              
29             The main subroutine get a number and give a chinese string which has been converted as currency
30             upper case for finance processing. As Check or Invoce that need.
31              
32             0 : 0
33             0.03 : 零叁分
34             1.04 : 壹圆零肆分
35             -12.00 : 壹拾贰圆整
36             102.15 : 壹佰零贰圆壹角伍分
37             2004 : 贰仟零肆圆整
38             50142 : 伍万零壹佰肆拾贰圆整
39             400102 : 肆拾万零壹佰零贰圆整
40             50000045.01 : 伍仟万零肆拾伍圆零壹分
41             123456789.00 : 壹亿贰仟叁佰肆拾伍万陆仟柒佰捌拾玖圆整
42             9876543219876.123 : 9876543219876.123
43              
44             =head2 chinese_currency_uc( $number )
45              
46             my $words = chinese_currency_uc( 123.45 );
47             my $words = chinese_currency_uc( 123.45 );
48              
49             The number is only 12 interger length and the float will restrict to 2 length,
50             ortherwise it just return the orignal number which passed in. If the number is
51             negotive, we just ignore the '-'.
52              
53             chinese_currency_uc is auto exported.
54              
55             =cut
56              
57             sub chinese_currency_uc {
58 11     11 1 8470 my $given = shift;
59 11 100 66     341 return 0 if ( not defined $given or $given == 0 );
60              
61 10         75 my $number = sprintf( "%.2f", $given );
62              
63             # split the number into two parts
64 10         31 my ( $integer, $float ) = split(/\./, $number );
65 10 100 66     444 return $given if length($integer) > 12 or length($float) > 2;
66            
67             # parse the interger
68 9         11 my @chunks; push @chunks, $1 while ($integer =~ s/(\d{1,4})$//g);
  9         97  
69 14         35 my $string = join ( '',
70             reverse
71 9         20 map { _convert_integer_every_four_digits( $chunks[$_], $_*4 ) }
72             ( 0 .. $#chunks )
73             );
74            
75             # parse the float as needed
76 9 100       26 unless ( $float == 0 ){
77 4         7 my $count = -1;
78 8         9 $string .= join ( '',
79 4 100       15 map { $count++; ( $_ == 0 ) ? $_ : $dig{$_}.$float_unit[ $count ]; }
  8         35  
80             split( //, $float )
81             );
82 4         17 $string =~ s/0{1,}$//g;
83              
84             # or just append the word
85             }else{
86 5         11 $string .= '整';
87             }
88              
89             # make the temp '0' or '000' like to be one chinese word
90 9         45 $string =~ s/0{1,}/$dig{0}/g;
91              
92             # here we done
93 9         3456 return $string;
94             }
95              
96             =head2 _convert_integer_every_four_digits( $number, $start_point )
97              
98             here the $number is a number which maxlength is 4. The $start_point is an array index refer
99             to @integer_unit. Returns a string which temporily converted, and contains some alpha number
100             0 to suit later handling.
101              
102             It is the private subroutine, so just leave it be.
103              
104             =cut
105              
106             sub _convert_integer_every_four_digits {
107 14     14   20 my $number = shift;
108 14         17 my $start = shift;
109            
110 14         17 my $count = $start - 1;
111            
112 14         21 my $string = $number;
113 14 100       32 unless ( $number == 0 ){
114 38         40 $string = join ('',
115             reverse map {
116 13         31 $count++;
117 38 100       144 ( $_ == 0 )
118             ? $_
119             : $dig{$_}.$integer_unit[ $count ];
120             } reverse split(//,$number)
121             );
122 13         48 $string =~ s/0{1,3}$/$integer_unit[ $start ]/g;
123             }
124            
125 14         48 return $string;
126             }
127              
128             1;
129             __END__