[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
- Subject: SF.net SVN: ledger-smb:[5285] addons/1.3/report_framework/trunk/LedgerSMB
- From: ..hidden..
- Date: Wed, 28 Nov 2012 09:22:03 +0000
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.