All other files, make sure that either assetName, macroName or topicName is defined in the i18n file. Make sure that all Assets have assetName defined in their definition sub.
476 lines
13 KiB
Perl
476 lines
13 KiB
Perl
package WebGUI::Asset::Wobject::StockData;
|
|
|
|
#-------------------------------------------------------------------
|
|
# WebGUI is Copyright 2001-2005 Plain Black Corporation.
|
|
#-------------------------------------------------------------------
|
|
# Please read the legal notices (docs/legal.txt) and the license
|
|
# (docs/license.txt) that came with this distribution before using
|
|
# this software.
|
|
#-------------------------------------------------------------------
|
|
# http://www.plainblack.com info@plainblack.com
|
|
#-------------------------------------------------------------------
|
|
|
|
use strict;
|
|
use WebGUI::ErrorHandler;
|
|
use WebGUI::Icon;
|
|
use WebGUI::International;
|
|
use WebGUI::Privilege;
|
|
use WebGUI::Session;
|
|
use WebGUI::SQL;
|
|
use WebGUI::URL;
|
|
use WebGUI::Utility;
|
|
use WebGUI::Asset::Wobject;
|
|
|
|
use Finance::Quote;
|
|
|
|
our @ISA = qw(WebGUI::Asset::Wobject);
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _appendStockVars ( hash, data, symbol )
|
|
|
|
Appends stock variables for the symbol passed in to the hash passed in
|
|
|
|
=head3 hash
|
|
|
|
hash to append stock variables to
|
|
|
|
=head3 data
|
|
|
|
hash reference in the format passed by the fetch method from Finance::Quote
|
|
|
|
=head3 symbol
|
|
|
|
stock symbol to append variables for
|
|
|
|
=cut
|
|
|
|
sub _appendStockVars {
|
|
my $self = shift;
|
|
my $hash = $_[0];
|
|
my $data = $_[1];
|
|
my $symbol = $_[2];
|
|
$hash->{'stocks.symbol'} = _na($symbol);
|
|
$hash->{'stocks.name'} = _na($data->{$symbol,"name"});
|
|
$hash->{'stocks.last'} = _na($data->{$symbol,"last"});
|
|
$hash->{'stocks.high'} = _na($data->{$symbol,"high"});
|
|
$hash->{'stocks.low'} = _na($data->{$symbol,"low"});
|
|
$hash->{'stocks.date'} = _na($data->{$symbol,"date"});
|
|
$hash->{'stocks.time'} = _na($data->{$symbol,"time"});
|
|
|
|
$hash->{'stocks.net'} = _na($data->{$symbol,"net"});
|
|
$hash->{'stocks.net.isDown'} = $hash->{'stocks.net'} < 0;
|
|
$hash->{'stocks.net.isUp'} = $hash->{'stocks.net'} > 0;
|
|
$hash->{'stocks.net.noChange'} = $hash->{'stocks.net'} == 0;
|
|
|
|
$hash->{'stocks.net.icon'} = "nc.gif";
|
|
if($hash->{'stocks.net.isDown'}) {
|
|
$hash->{'stocks.net.icon'} = "down.gif";
|
|
} elsif($hash->{'stocks.net.isUp'}) {
|
|
$hash->{'stocks.net.icon'} = "up.gif";
|
|
}
|
|
$hash->{'stocks.p_change'} = _na($data->{$symbol,"p_change"});
|
|
$hash->{'stocks.volume'} = _na($data->{$symbol,"volume"});
|
|
$hash->{'stocks.volume.millions'} = _na(WebGUI::Utility::round(($hash->{'stocks.volume'}/1000000),2));
|
|
$hash->{'stocks.avg_vol'} = _na($data->{$symbol,"avg_vol"});
|
|
$hash->{'stocks.bid'} = _na($data->{$symbol,"bid"});
|
|
$hash->{'stocks.ask'} = _na(WebGUI::Utility::commify($data->{$symbol,"ask"}));
|
|
$hash->{'stocks.close'} = _na($data->{$symbol,"close"});
|
|
$hash->{'stocks.open'} = _na($data->{$symbol,"open"});
|
|
$hash->{'stocks.day_range'} = _na($data->{$symbol,"day_range"});
|
|
$hash->{'stocks.year_range'} = _na($data->{$symbol,"year_range"});
|
|
my ($yrLo,$yrHi) = split("-",$hash->{'stocks.year_range'});
|
|
|
|
$hash->{'stocks.year_high'} = _na($self->_trim($yrHi));
|
|
$hash->{'stocks.year_low'} = _na($self->_trim($yrLo));
|
|
$hash->{'stocks.eps'} = _na($data->{$symbol,"eps"});
|
|
$hash->{'stocks.pe'} = _na($data->{$symbol,"pe"});
|
|
$hash->{'stocks.div_date'} = _na($data->{$symbol,"div_date"});
|
|
$hash->{'stocks.div'} = _na($data->{$symbol,"div"});
|
|
$hash->{'stocks.div_yield'} = _na($data->{$symbol,"div_yield"});
|
|
$hash->{'stocks.cap'} = _na(lc($data->{$symbol,"cap"}));
|
|
$hash->{'stocks.ex_div'} = _na($data->{$symbol,"ex_div"});
|
|
$hash->{'stocks.nav'} = _na($data->{$symbol,"nav"});
|
|
$hash->{'stocks.yield'} = _na($data->{$symbol,"yield"});
|
|
$hash->{'stocks.exchange'} = _na($data->{$symbol,"exchange"});
|
|
$hash->{'stocks.success'} = _na($data->{$symbol,"success"});
|
|
$hash->{'stocks.errormsg'} = _na($data->{$symbol,"errormsg"});
|
|
$hash->{'stocks.method'} = _na($data->{$symbol,"method"});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _na( string )
|
|
|
|
If string passed in is empty, returns N/A
|
|
|
|
=head3 string
|
|
|
|
a string
|
|
|
|
=cut
|
|
|
|
sub _na {
|
|
my $str = $_[0];
|
|
unless($str) {
|
|
$str = "N/A";
|
|
}
|
|
return $str;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _appendZero( intger )
|
|
|
|
Appends a zero to an integer if it is 0-9
|
|
|
|
=head3 integer
|
|
|
|
an integer
|
|
|
|
=cut
|
|
|
|
sub _appendZero {
|
|
my $self = shift;
|
|
my $num = $_[0];
|
|
if (length($num) == 1) {
|
|
$num = "0".$num;
|
|
}
|
|
return $num;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _clearStockEditSession ( )
|
|
|
|
Clears the session variables from session used by the stock list edit form
|
|
|
|
=cut
|
|
|
|
sub _clearStockEditSession {
|
|
my $self = shift;
|
|
$session{form}{symbol} = "";
|
|
$session{form}{stockId} = "";
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _convertToEpoch (date,time)
|
|
|
|
Converts the date and time returned by Finance::Quote to an epoch
|
|
|
|
=head3 date
|
|
|
|
date format returned by Finance::Quote
|
|
|
|
=head3 time
|
|
|
|
time format returned by Finance::Quote
|
|
|
|
=cut
|
|
|
|
sub _convertToEpoch {
|
|
my $self = shift;
|
|
my $date = $_[0];
|
|
my $time = $_[1];
|
|
|
|
my ($month,$day,$year) = split("/",$date);
|
|
$month = $self->_appendZero($month);
|
|
$day = $self->_appendZero($day);
|
|
my $tfixed = substr($time,0,-2);
|
|
my ($hour,$minute) = split(":",$tfixed);
|
|
if($time =~ m/pm/i) {
|
|
$hour += 12;
|
|
}
|
|
$hour = $self->_appendZero($hour);
|
|
$minute = $self->_appendZero($minute);
|
|
return WebGUI::DateTime::humanToEpoch("$year-$month-$day $hour:$minute:00");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _getStocks ( stocks )
|
|
|
|
Private method which retrieves stock information from the Finance::Quote package
|
|
|
|
=head3 stocks
|
|
|
|
list of stock symbols to find passed in as an array reference. stock symbols should all be uppercase
|
|
|
|
=cut
|
|
|
|
sub _getStocks {
|
|
my $self = shift;
|
|
my $stocks = $_[0];
|
|
#Create a new Finance::Quote object
|
|
my $q = Finance::Quote->new;
|
|
#Disable failover if specified
|
|
unless ($self->getValue("failover")) {
|
|
$q->failover(0);
|
|
}
|
|
#Fetch the stock information and return the results
|
|
return $q->fetch($self->getValue("source"),@{$stocks});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _getStockSources ( )
|
|
|
|
Private method which retrieves the list of available stock sources from Finance::Quote package
|
|
and returns the results as a hash reference for the selectList Form API
|
|
|
|
=cut
|
|
|
|
sub _getStockSources {
|
|
my $self = shift;
|
|
#Instantiate Finance::Quote
|
|
my $q = Finance::Quote->new;
|
|
#Retrieve array of available sources and sort them
|
|
my @srcs = sort $q->sources;
|
|
#Create a hash reference with the name referencing itself
|
|
my %sources;
|
|
#Tie to IxHash to preserve alphabetical order
|
|
tie %sources, "Tie::IxHash";
|
|
foreach my $src (@srcs) {
|
|
$sources{$src} = $src;
|
|
}
|
|
return \%sources;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _submenu
|
|
|
|
renders the admin console view
|
|
|
|
=cut
|
|
|
|
sub _submenu {
|
|
my $self = shift;
|
|
my $workarea = shift;
|
|
my $title = shift;
|
|
my $help = shift;
|
|
my $ac = WebGUI::AdminConsole->new("editstocks");
|
|
$ac->setHelp($help) if ($help);
|
|
$ac->setIcon($self->getIcon);
|
|
return $ac->render($workarea, $title);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 _trim (str)
|
|
|
|
Trims whitespace form front and end of a string
|
|
|
|
=head3 str
|
|
|
|
a string to trim
|
|
|
|
=cut
|
|
|
|
sub _trim {
|
|
my $self = shift;
|
|
my $str = $_[0];
|
|
$str =~ s/^\s//;
|
|
$str =~ s/\s$//;
|
|
return $str;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 definition
|
|
|
|
defines wobject properties for Stock Data instances
|
|
|
|
=cut
|
|
|
|
sub definition {
|
|
my $class = shift;
|
|
my $definition = shift;
|
|
my $properties = {
|
|
templateId =>{
|
|
fieldType=>"template",
|
|
defaultValue=>'StockDataTMPL000000001'
|
|
},
|
|
displayTemplateId=>{
|
|
fieldType=>"template",
|
|
defaultValue=>'StockDataTMPL000000002'
|
|
},
|
|
defaultStocks=>{
|
|
fieldType=>"textarea",
|
|
defaultValue=>"DELL\nMSFT\nORCL\nSUNW\nYHOO"
|
|
},
|
|
source=>{
|
|
fieldType=>"selectList",
|
|
defaultValue=>"usa"
|
|
},
|
|
failover=>{
|
|
fieldType=>"checkbox",
|
|
defaultValue=>undef
|
|
}
|
|
};
|
|
push(@{$definition}, {
|
|
tableName=>'StockData',
|
|
className=>'WebGUI::Asset::Wobject::StockData',
|
|
icon=>'stockData.gif',
|
|
assetName=>WebGUI::International::get("assetName","Asset_StockData"),
|
|
properties=>$properties
|
|
});
|
|
return $class->SUPER::definition($definition);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 getEditForm
|
|
|
|
returns the tabform object that will be used in generating the edit page for Stock Lists
|
|
|
|
=cut
|
|
|
|
sub getEditForm {
|
|
my $self = shift;
|
|
my $tabform = $self->SUPER::getEditForm();
|
|
|
|
$tabform->getTab("display")->template(
|
|
-value=>$self->get("templateId"),
|
|
-label=>WebGUI::International::get("template_label","Asset_StockData"),
|
|
-namespace=>"StockData"
|
|
);
|
|
|
|
$tabform->getTab("display")->template(
|
|
-value=>$self->get("displayTemplateId"),
|
|
-label=>WebGUI::International::get("display_template_label","Asset_StockData"),
|
|
-namespace=>"StockData/Display"
|
|
);
|
|
|
|
$tabform->getTab("properties")->textarea(
|
|
-name => "defaultStocks",
|
|
-label=> WebGUI::International::get("default_stock_label","Asset_StockData"),
|
|
-value=> $self->getValue("defaultStocks")
|
|
);
|
|
|
|
$tabform->getTab("properties")->selectList(
|
|
-name => "source",
|
|
-label=> WebGUI::International::get("stock_source","Asset_StockData"),
|
|
-options=>$self->_getStockSources(),
|
|
-value=> [$self->getValue("source")],
|
|
-hoverHelp=>WebGUI::International::get("stock_source_description","Asset_StockData")
|
|
);
|
|
|
|
$tabform->getTab("properties")->yesNo(
|
|
-name=> "failover",
|
|
-label=> WebGUI::International::get("failover_label","Asset_StockData"),
|
|
-value=>$self->getValue("failover"),
|
|
-hoverHelp=> WebGUI::International::get("failover_description","Asset_StockData")
|
|
);
|
|
|
|
return $tabform;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 purge ( )
|
|
|
|
removes collateral data associated with a StockData when the system
|
|
purges it's data.
|
|
|
|
=cut
|
|
|
|
sub purge {
|
|
my $self = shift;
|
|
return $self->SUPER::purge;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 view ( )
|
|
|
|
method called by the www_view method. Returns a processed template
|
|
to be displayed within the page style
|
|
|
|
=cut
|
|
|
|
sub view {
|
|
my $self = shift;
|
|
my $var = {};
|
|
#Set some template variables
|
|
$var->{'extrasFolder'} = $session{config}{extrasURL}."/wobject/StockData";
|
|
$var->{'editUrl'} = $self->getUrl("func=editStocks");
|
|
$var->{'isVisitor'} = $session{user}{userId} eq 1;
|
|
$var->{'stock.display.url'} = $self->getUrl("func=displayStock&symbol=");
|
|
|
|
#Build list of stocks as an array
|
|
my $defaults = $self->getValue("defaultStocks");
|
|
#replace any windows newlines
|
|
$defaults =~ s/\r//;
|
|
my @array = split("\n",$defaults);
|
|
#trim default stocks of whitespace
|
|
for (my $i = 0; $i < scalar(@array); $i++) {
|
|
$array[$i] = $self->_trim($array[$i]);
|
|
}
|
|
my $data = $self->_getStocks(\@array);
|
|
|
|
my @stocks = ();
|
|
foreach my $symbol (@array) {
|
|
my $hash = {};
|
|
|
|
#Append Template Variables for stock symbol
|
|
$self->_appendStockVars($hash,$data,$symbol);
|
|
|
|
#Create last update date formats
|
|
unless ($var->{'lastUpdate.default'}) {
|
|
my $luEpoch = $self->_convertToEpoch($hash->{'stocks.date'},$hash->{'stocks.time'});
|
|
$var->{'lastUpdate.intl'} = WebGUI::DateTime::epochToHuman($luEpoch,"%y-%m-%d %j:%n");
|
|
$var->{'lastUpdate.us'} = WebGUI::DateTime::epochToHuman($luEpoch,"%m/%d/%y %h:%n %p");
|
|
$var->{'lastUpdate.default'} = WebGUI::DateTime::epochToHuman($luEpoch,"%C %d %H:%n %P");
|
|
}
|
|
|
|
push (@stocks, $hash);
|
|
}
|
|
$var->{'stocks.loop'} = \@stocks;
|
|
return $self->processTemplate($var, $self->get("templateId"));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 www_displayStock ( )
|
|
|
|
Web facing method which allows users to view details about their stocks
|
|
|
|
=cut
|
|
|
|
sub www_displayStock {
|
|
my $self = shift;
|
|
my $var = {};
|
|
return WebGUI::Privilege::noAccess() unless $self->canView();
|
|
|
|
$var->{'extrasFolder'} = $session{config}{extrasURL}."/wobject/StockData";
|
|
|
|
my $symbol = $session{form}{symbol};
|
|
my $data = $self->_getStocks([$symbol]);
|
|
#Append Template Variables for stock symbol
|
|
$self->_appendStockVars($var,$data,$symbol);
|
|
|
|
#Configure last update dates
|
|
my $luEpoch = $self->_convertToEpoch($var->{'stocks.date'},$var->{'stocks.time'});
|
|
$var->{'lastUpdate.intl'} = WebGUI::DateTime::epochToHuman($luEpoch,"%y-%m-%d");
|
|
$var->{'lastUpdate.us'} = WebGUI::DateTime::epochToHuman($luEpoch,"%m/%d/%y");
|
|
|
|
$session{setting}{showDebug} = 0;
|
|
return $self->processTemplate($var, $self->get("displayTemplateId"));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
#=head2 www_edit ( )
|
|
|
|
#Web facing method which is the default edit page
|
|
|
|
#=cut
|
|
|
|
#sub www_edit {
|
|
# my $self = shift;
|
|
# return WebGUI::Privilege::insufficient() unless $self->canEdit;
|
|
# $self->getAdminConsole->setHelp("stock list add/edit","Asset_StockData");
|
|
# return $self->getAdminConsole->render($self->getEditForm->print,
|
|
# WebGUI::International::get("edit_title","Asset_StockData"));
|
|
#}
|
|
|
|
#-------------------------------------------------------------------
|
|
=head2 www_view ( )
|
|
|
|
Overwrite www_view method and call the superclass object, passing in a 1 to disable cache
|
|
|
|
=cut
|
|
|
|
sub www_view {
|
|
my $self = shift;
|
|
$self->SUPER::www_view(1);
|
|
}
|
|
|
|
1;
|