[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb:[5285] addons/1.3/report_framework/trunk/LedgerSMB



Revision: 5285
          http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=5285&view=rev
Author:   einhverfr
Date:     2012-11-28 09:22:02 +0000 (Wed, 28 Nov 2012)
Log Message:
-----------
Adding accidently omitted classes

Added Paths:
-----------
    addons/1.3/report_framework/trunk/LedgerSMB/PGDate.pm
    addons/1.3/report_framework/trunk/LedgerSMB/PGNumber.pm

Added: addons/1.3/report_framework/trunk/LedgerSMB/PGDate.pm
===================================================================
--- addons/1.3/report_framework/trunk/LedgerSMB/PGDate.pm	                        (rev 0)
+++ addons/1.3/report_framework/trunk/LedgerSMB/PGDate.pm	2012-11-28 09:22:02 UTC (rev 5285)
@@ -0,0 +1,242 @@
+=head1 NAME
+LedgerSMB::PgDate
+
+=cut
+
+package LedgerSMB::PGDate;
+use Moose;
+use DateTime::Format::Strptime;
+use Carp;
+
+BEGIN {
+   use LedgerSMB::SODA;
+   LedgerSMB::SODA->register_type({sql_type => 'date', 
+                                 perl_class => 'LedgerSMB::PGDate'});
+   LedgerSMB::SODA->register_type({sql_type => 'datetime', 
+                                 perl_class => 'LedgerSMB::PGDate'});
+   LedgerSMB::SODA->register_type({sql_type => 'timestamp', 
+                                 perl_class => 'LedgerSMB::PGDate'});
+}
+
+=head1 SYNPOSIS
+This class handles formatting and mapping between the DateTime module and
+PostgreSQL. It provides a handler for date and timestamp datatypes.
+
+=head1 PROPERTIES
+
+=over
+
+=item date
+A DateTime object for internal storage and processing.
+
+=cut
+
+has date => (isa => 'Maybe[DateTime]', is=> 'ro', required => '1');
+
+=back
+
+=head1 SUPPORTED FORMATS
+
+Formats are written with hyphens as separators.  You can actually use any other
+character other than D, M, or Y as the separator, so instead of YYYY-MM-DD, you
+could have YYYY/MM/DD, YYYY!MM!DD, etc.
+
+On the database side, these are all converted to YYYY-MM-DD format.
+
+=over
+
+=item 'YYYY-MM-DD'
+
+=item DD-MM-YYYY
+
+
+=item DD/MM/YYYY
+
+=item MM-DD-YYYY
+
+=item MM/DD/YYYY 
+
+=item YYYYMMDD
+
+=item YYMMDD
+
+=item DDMMYYYY
+
+=item DDMMYY
+
+=item MMDDYYYY
+
+=item MMDDYY
+
+=item DDmonYYYY
+
+=cut
+
+our $formats = { 
+    'YYYY-MM-DD' => ['%F'],
+    'DD-MM-YYYY' => ['%d-%m-%Y', '%d-%m-%y'],
+    'DD/MM/YYYY' => ['%d/%m/%Y', '%D'],
+    'MM-DD-YYYY' => ['%m-%d-%Y', '%m-%d-%y'],
+    'MM/DD/YYYY' => ['%d/%m/%Y', '%d/%m/%y'],
+      'YYYYMMDD' => ['%Y%m%d'],
+        'YYMMDD' => ['%y%m%d'],
+      'DDMMYYYY' => ['%d%m%Y'],
+        'DDMMYY' => ['%d%m%y'],
+      'MMDDYYYY' => ['%m%d%Y'],
+        'MMDDYY' => ['%m%d%y'],
+     'DDmonYYYY' => ['%d%b%Y', '%d%b%y']
+};
+
+=back
+
+=head1 CONSTRUCTOR SYNTAX
+
+LedgerSMB::PgDate->new({ date => DateTime->new(year => 2012, day => 31, month =>
+12)});
+
+Note the constructor here is private, and not intended to be called directly.
+
+Use from_db and from_input methods instead since these handle appropriately 
+different formats and handle construction differently.
+
+=cut
+
+
+=head1 METHODS
+
+=over
+
+=item from_input($string date, optional $has_time)
+
+Parses this from an input string according to the user's dateformat
+
+Input parsing iterates through formats specified for the format string.  If
+$has_time is set and true, or if it is not defined then ' %T' is added to the
+end of the format string.  Similarly, if $has_time is undef or set and false,
+the format is used as is.  This allows the calling scripts to specify either
+that the string includes a time portion or that it does not, and allows this
+module to handle the parsing.
+
+=cut
+
+# Private method _parse_string($string, $format, $has_time)
+# Implements above parsing spec
+
+sub _parse_string {
+    my ($self, $string, $format, $has_time) = @_;
+    $string = undef if $string eq '';
+    return undef if !defined $string;
+    if (!defined $LedgerSMB::App_State::Locale->{datetime}){
+        $LedgerSMB::App_State::Locale->{datetime} = 'en_US';
+    }
+    for my $fmt (@{$formats->{$format}}){
+        if ($has_time or ! defined $has_time){
+            my $parser = new DateTime::Format::Strptime(
+                     pattern => $fmt . ' %T',
+                      locale => $LedgerSMB::App_State::Locale->{datetime},
+            );
+            if (my $dt = $parser->parse_datetime($string)){
+                return $dt;
+            } 
+        }
+        if (!$has_time or ! defined $has_time){
+            my $parser = new DateTime::Format::Strptime(
+                     pattern => $fmt,
+                      locale => $LedgerSMB::App_State::Locale->{datetime},
+            );
+            if (my $dt = $parser->parse_datetime($string)){
+                return $dt;
+            }
+        }
+    }
+}
+
+sub from_input{
+    my ($self, $input, $has_time) = @_;
+    return $input if eval {$input->isa(__PACKAGE__)};
+    $input = undef if $input eq '';
+    return undef if !defined $input;
+    my $format = $LedgerSMB::App_State::User->{dateformat};
+    my $dt =  _parse_string($self, $input, uc($format), $has_time);
+    return $self->new({date => $dt});
+}
+
+
+=item to_output(optional string $format)
+
+This returns the human readable formatted date.  If $format is supplied, it is 
+used.  If $format is not supplied, the dateformat of the user is used.
+
+=cut
+
+sub to_output {
+    my ($self) = @_;
+    return undef if !defined $self->date;
+    my $fmt;
+    if (defined $LedgerSMB::App_State::User->{dateformat}){
+        $fmt = $formats->{uc($LedgerSMB::App_State::User->{dateformat})}->[0];
+    } else {
+        $fmt = '%F';
+    }
+    
+    my $formatter = new DateTime::Format::Strptime(
+             pattern => $fmt,
+              locale => $LedgerSMB::App_State::Locale->{datetime},
+            on_error => 'croak',
+    );
+    return $formatter->format_datetime($self->date);
+}
+
+=item from_db (string $date, string $type)
+
+The $date is the date or datetime value from the db. The type is either 'date',
+'timestamp', or 'datetime'.
+
+=cut
+
+sub from_db {
+    use Carp;
+    my ($self, $input, $type) = @_;
+    return undef if !defined $input;
+    my $format = 'YYYY-MM-DD';
+    my $has_time;
+    if ((lc($type) eq 'datetime') or (lc($type) eq 'timestamp')) {
+        $has_time = 1;
+    } elsif(lc($type) eq 'date'){
+        $has_time = 0;
+    } else {
+       confess 'LedgerSMB::PGDate Invalid DB Type';
+    }
+    my $dt =  _parse_string($self, $input, $format, $has_time);
+    return $self->new({date => $dt});
+}
+
+=item to_db
+This returns the preferred form for database queries.
+
+=cut
+
+sub to_db {
+    my ($self) = @_;
+    return undef if !defined $self->date;
+    my $fmt = $formats->{'YYYY-MM-DD'}->[0];
+    $fmt .= ' %T' if ($self->date->hour);
+    my $formatter = new DateTime::Format::Strptime(
+             pattern => $fmt,
+              locale => $LedgerSMB::App_State::Locale->{datetime},
+            on_error => 'croak',
+    );
+    return $formatter->format_datetime($self->date);
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+=back
+
+=head1 Copyright (C) 2011, The LedgerSMB core team.
+
+This file is licensed under the Gnu General Public License version 2, or at your
+option any later version.  A copy of the license should have been included with
+your software.

Added: addons/1.3/report_framework/trunk/LedgerSMB/PGNumber.pm
===================================================================
--- addons/1.3/report_framework/trunk/LedgerSMB/PGNumber.pm	                        (rev 0)
+++ addons/1.3/report_framework/trunk/LedgerSMB/PGNumber.pm	2012-11-28 09:22:02 UTC (rev 5285)
@@ -0,0 +1,242 @@
+=head1 NAME
+
+LedgerSMB::PGNumeric
+
+=cut
+
+use strict;
+use warnings;
+use Number::Format;
+use LedgerSMB::Setting;
+
+package LedgerSMB::PGNumber;
+
+BEGIN {
+   use LedgerSMB::SODA;
+   LedgerSMB::SODA->register_type({sql_type => 'float', 
+                                 perl_class => 'LedgerSMB::PGNumber'});
+   LedgerSMB::SODA->register_type({sql_type => 'double', 
+                                 perl_class => 'LedgerSMB::PGNumber'});
+   LedgerSMB::SODA->register_type({sql_type => 'numeric', 
+                                 perl_class => 'LedgerSMB::PGNumber'});
+}
+
+=head1 SYNPOSIS
+
+This is a wrapper class for handling a database interface for numeric (int, 
+float, numeric) data types to/from the database and to/from user input.
+
+This extends Math::BigFloat and can be used in this way.
+
+=head1 INHERITS
+
+=over
+
+=item Math::BigFloat
+
+=back
+
+=cut
+
+use base qw(Math::BigFloat);
+
+=head1 SUPPORTED I/O FORMATS
+
+=over
+
+=item 1000.00 (default)
+
+=item 1000,00
+
+=item 1 000.00
+
+=item 1 000,00
+
+=item 1,000.00
+
+=item 1.000,00
+
+=item 1'000,00
+
+=item 1'000.00
+
+=cut
+
+our $lsmb_formats = {
+      "1000.00" => { thousands_sep => '',  decimal_sep => '.' },
+
+      "1000,00" => { thousands_sep => '',  decimal_sep => ',' },
+     "1 000.00" => { thousands_sep => ' ', decimal_sep => '.' },
+     "1 000,00" => { thousands_sep => ' ', decimal_sep => ',' },
+     "1,000.00" => { thousands_sep => ',', decimal_sep => '.' },
+     "1.000,00" => { thousands_sep => '.', decimal_sep => ',' },
+     "1'000,00" => { thousands_sep => "'", decimal_sep => ',' },
+     "1'000.00" => { thousands_sep => "'", decimal_sep => '.' },
+
+};
+
+=back
+
+=head1 SUPPORTED NEGATIVE FORMATS
+
+All use 123.45 as an example.
+
+=over
+
+=item def (DEFAULT)
+
+positive:  123.45
+negative: -123.45
+
+=item DRCR
+
+positive:  123.45 CR
+negative:  123.45 DR
+
+=item paren
+
+positive:  123.45
+negative: (123.45)
+
+=cut
+
+my $lsmb_neg_formats = {
+  'def' => { pos => '%s',   neg => '-%s'   },
+ 'DRCR' => { pos => '%s CR', neg => '%s DR' },
+'paren' => { pos => '%s',   neg => '(%s)'  },
+};
+
+=back
+
+=head1 IO METHODS
+
+=over
+
+=item from_input(string $input, hashref %args);
+
+The input is formatted.
+
+=cut
+
+sub from_input {
+    my $self   = shift @_;
+    my $string = shift @_;
+    $string = undef if $string eq '';
+    my %args   = (ref($_[0]) eq 'HASH')? %{$_[0]}: @_;  
+    my $format = ($args{format}) ? $args{format}
+                              : $LedgerSMB::App_State::User->{numberformat};
+    die 'LedgerSMB::PGNumber No Format Set' if !$format;
+    return undef if !defined $string;
+    my $negate;
+    my $pgnum;
+    my $newval;
+    $negate = 1 if $string =~ /(^\(|DR$)/;
+    if ( UNIVERSAL::isa( $string, 'LedgerSMB::PGNumber' ) )
+    {    
+        return $string;
+    }
+    if (UNIVERSAL::isa( $string, 'Math::BigFloat' ) ) {
+        $pgnum = $string; 
+    } else {
+        my $formatter = new Number::Format(
+                    -thousands_sep => $lsmb_formats->{$format}->{thousands_sep},
+                    -decimal_point => $lsmb_formats->{$format}->{decimal_sep},
+        );
+        $newval = $formatter->unformat_number($string);
+        $pgnum = Math::BigFloat->new($newval);
+        $self->round_mode('+inf');
+    } 
+    bless $pgnum, $self;
+    $pgnum->bmul(-1) if $negate;
+    die 'LedgerSMB::PGNumber Invalid Number' if $pgnum->is_nan();
+    return $pgnum;
+}
+
+=item to_output($hashref or %hash);
+
+All arguments are optional.  Hash or hashref arguments include
+
+=over
+
+=item format
+
+Override user's default output format with specified format for this number.
+
+=item places
+
+Specifies the number of places to round
+
+=item money
+
+Specifies to round to configured number format for money
+
+=item neg_format
+
+Specifies the negative format
+
+=item locale
+
+=back
+
+=cut
+
+sub to_output {
+    my $self = shift @_;
+    my %args  = (ref($_[0]) eq 'HASH')? %{$_[0]}: @_;  
+    my $is_neg = $self->is_neg;
+
+    my $format = ($args{format}) ? $args{format}
+                              : $LedgerSMB::App_State::User->{numberformat};
+
+    my $places = undef;
+    $places = LedgerSMB::Setting->get('decimal_places') if $args{money};
+    $places = ($args{places}) ? $args{places} : $places;
+    my $str = $self->bstr;
+    my $dplaces = $places;
+    $places = 0 unless defined $places and ($places > 0);
+    my $zfill = ($places > 0) ? 1 : 0;
+    $dplaces = 5 unless defined $dplaces;
+    my $formatter = new Number::Format(
+                    -thousands_sep => $lsmb_formats->{$format}->{thousands_sep},
+                    -decimal_point => $lsmb_formats->{$format}->{decimal_sep},
+                     -decimal_fill => $zfill,
+                       -neg_format => 'x');   
+    $str = $formatter->format_number($str, $dplaces);
+
+    my $neg_format = ($args{neg_format}) ? $args{neg_format} : 'def';
+    my $fmt = ($is_neg) ? $lsmb_neg_formats->{$neg_format}->{neg}
+                        : $lsmb_neg_formats->{$neg_format}->{pos};
+   
+    return sprintf($fmt, $str);
+}
+
+=item from_db
+
+=cut
+
+sub from_db {
+    my ($self, $string) = @_;
+    return undef if !defined $string;
+    return $self->new($string);
+}
+
+=item to_db
+
+=cut
+
+sub to_db {
+    my ($self) = @_; 
+    return $self->to_output({format => '1000.00'});
+}
+
+
+1;
+
+=back
+
+=head1 Copyright (C) 2011, The LedgerSMB core team.
+
+This file is licensed under the Gnu General Public License version 2, or at your
+option any later version.  A copy of the license should have been included with
+your software.
+

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.