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

SF.net SVN: ledger-smb:[6927] addons/1.3/wxPOS-simple



Revision: 6927
          http://sourceforge.net/p/ledger-smb/code/6927
Author:   einhverfr
Date:     2014-03-07 05:12:58 +0000 (Fri, 07 Mar 2014)
Log Message:
-----------
New reports added: stock list and purchase history.  Also fixed pruchases showing up as sales.

Modified Paths:
--------------
    addons/1.3/wxPOS-simple/WXPOS/Invoice.pm
    addons/1.3/wxPOS-simple/WXPOS/Part.pm
    addons/1.3/wxPOS-simple/WXPOS/Sysconfig.pm
    addons/1.3/wxPOS-simple/WXPOS/Template/LaTeX.pm
    addons/1.3/wxPOS-simple/WXPOS/Template.pm
    addons/1.3/wxPOS-simple/WXPOS/UI/AP.pm
    addons/1.3/wxPOS-simple/WXPOS/UI/AR.pm
    addons/1.3/wxPOS-simple/WXPOS/UI/IC.pm
    addons/1.3/wxPOS-simple/WXPOS/UI/Login.pm
    addons/1.3/wxPOS-simple/WXPOS/UI.pm
    addons/1.3/wxPOS-simple/setup/functions.sql

Added Paths:
-----------
    addons/1.3/wxPOS-simple/WXPOS/Purchase_History.pm
    addons/1.3/wxPOS-simple/WXPOS/Stocklist.pm
    addons/1.3/wxPOS-simple/WXPOS/UI/History.pm
    addons/1.3/wxPOS-simple/setup/Parts.sql
    addons/1.3/wxPOS-simple/setup/purchase_history.sql
    addons/1.3/wxPOS-simple/templates/
    addons/1.3/wxPOS-simple/templates/invoice.tex
    addons/1.3/wxPOS-simple/templates/invoice.txt
    addons/1.3/wxPOS-simple/templates/letterhead.tex

Modified: addons/1.3/wxPOS-simple/WXPOS/Invoice.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Invoice.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/Invoice.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -17,6 +17,8 @@
 use Carp;
 use WXPOS::State;
 use WXPOS::Part;
+use WXPOS::Template;
+use DateTime;
 
 sub _get_prefix {
     return 'invoice__';
@@ -78,8 +80,17 @@
 
 =cut
 
-has transdate => (is => 'ro', default => sub { return 'today'} );
+has transdate => (is => 'ro', default => sub { return DateTime->now->ymd; } );
 
+=head2 printdate
+
+The date to print.
+
+=cut
+
+has printdate => (is => 'ro', default => sub { return DateTime->now->dmy; } );
+
+
 =head2 amount
 
 Invoice total
@@ -135,17 +146,10 @@
 
 =cut
 
-has payments => (is => 'ro', required => 1, isa => sub {_isa_payments(@_)});
+has payments => (is => 'ro');
 
-sub _isa_payments {
-    my ($payments) = @_;
-    foreach my $pmt (@$payments){
-        for my $key (qw(amount memo)){
-            croak "payment missing key $key" unless $pmt->{$key};
-        }
-    }
-}
 
+
 =head2 invoice_lines
 
 This is a list of invoice lines.  Each is a has ref which must contain the 
@@ -167,19 +171,10 @@
 
 =cut
 
-has invoice_lines => (is => 'ro', isa => sub {_isa_invoice_lines(@_)}, 
-                required => 1);
+has invoice_lines => (is => 'ro');
 
-sub _isa_invoice_lines {
-    my ($lines) = @_;
-    croak "No invoice lines" unless @$lines;
-    foreach my $line (@$lines){
-        for my $key (qw(partnumber qty sellprice)){
-            croak "Invoice line missing key $key" unless $line->{$key};
-        }
-    }
-}
 
+
 =head1 METHODS
 
 =head2 from_UI 
@@ -281,7 +276,16 @@
 =cut
 
 sub print {
-    # TODO
+    my ($self) = @_;
+	my $template = WXPOS::Template->new(
+	     path=> 'templates',
+		 template => 'invoice',
+		 noauto => 1,
+		 format => 'pdf',
+		 method => 'posprint',
+	);
+	$template->render($self);
+	return 1;
 }
 
 =head1 COPYRIGHT

Modified: addons/1.3/wxPOS-simple/WXPOS/Part.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Part.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/Part.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -77,6 +77,7 @@
     my $class = shift @_;
     return $autocomplete if defined $autocomplete;
     @{$autocomplete} = $class->call_procedure(funcname => 'list');
+	push @$autocomplete, {partnumber => 'zzzzz', description => 'zzzzz'} for (1 .. 12);
     return $autocomplete;
 }
 

Added: addons/1.3/wxPOS-simple/WXPOS/Purchase_History.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Purchase_History.pm	                        (rev 0)
+++ addons/1.3/wxPOS-simple/WXPOS/Purchase_History.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,63 @@
+=head1 NAME
+
+WXPOS::Purchase_History - Purchase History Report for WXPOS
+
+=head1 SYNOPSIS
+
+Note: @reportlines is a list of unblessed hashrefs
+
+  my @reportlines = WXPOS::Purchase_History->new(
+         from_date => $from, to_date => $to, description => $description)->get_lines;
+
+=cut
+  
+package WXPOS::Purchase_History;
+use Moo;
+with 'WXPOS::PGObject';
+
+=head1 DESCRIPTION
+
+This module provides a basic encapsulated interface to the purchase_history view.
+
+=head1 REPORT PROPERTIES
+
+=over
+
+=item month int
+
+=item year int
+
+=item description string
+
+=back
+
+=cut
+
+has month       => (is => 'ro', default => '1900-01-01');
+has year        => (is => 'ro', default => 'today');
+has description => (is => 'ro', default => '');
+
+sub _get_prefix { 'purchase_history__' }
+
+=head1 METHODS
+
+=head2 get_lines
+
+Returns the lines associated with the report.
+
+=cut
+sub get_lines {
+    my($self) = @_;
+	return $self->call_dbmethod(funcname => 'search');
+}
+
+=head1 COPYRIGHT
+
+Copyright (C) 2014 The LedgerSMB Core Team
+
+This file may be reused under the terms of the GNU General Public License
+version 2 or at your option any later version.
+
+=cut
+
+1;
\ No newline at end of file

Added: addons/1.3/wxPOS-simple/WXPOS/Stocklist.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Stocklist.pm	                        (rev 0)
+++ addons/1.3/wxPOS-simple/WXPOS/Stocklist.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,78 @@
+=head1 NAME
+
+WXPOS::StockList - Stock List Handling for WXPOS
+
+=head1 SYNPOSIS
+
+   my @entries = WXPOS::StockList->search($partnumber, $description);
+
+=head1 DESCRIPTION
+
+This module provides the basic framework for displaying the stock list.  
+It currently provides no possibilities for manipulating the numbers.
+
+=head1 PROPERTIES
+
+=over
+
+=item id int
+
+The id in the parts table.
+
+=item partnumber str
+
+=item description str
+
+=item sellprice numeric
+
+=item onhand numeric
+
+=back
+
+=cut
+
+package WXPOS::Stocklist;
+use Moo;
+with 'WXPOS::PGObject';
+
+has id          => (is => 'ro');
+has partnumber  => (is => 'ro');
+has description => (is => 'ro');
+has sellprice   => (is => 'ro');
+has onhand      => (is => 'ro');
+
+sub _get_prefix { 'stocklist__' }
+
+
+=head1 METHODS
+
+=head2 search($partnumber, $description)
+
+Both of these are substring searches.
+
+=cut
+
+sub search {
+    my ($self, $partnumber, $description) = @_;
+    my $tmp = __PACKAGE__->new(
+          id => '',
+          partnumber => "$partnumber",
+          description => "$description",
+          sellprice   => '',
+          onhand      => ''
+    );
+    my @items = $tmp->call_dbmethod(funcname => 'search');
+    $_ =  __PACKAGE__->new(%$_) for @items;
+    return @items;
+}
+
+=head1 COPYRIGHT
+
+Copyright 2014 The LedgerSMB Core Team.
+
+This file may be used under the terms of the GNU General Public License version
+2 or at your option any later version.
+
+=cut
+
+1;

Modified: addons/1.3/wxPOS-simple/WXPOS/Sysconfig.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Sysconfig.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/Sysconfig.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -18,6 +18,7 @@
 
 our $default_language = 'en';
 our $numberformat = '1.000';
+our $tempdir = $ENV{TEMP};
 
 our $dbconfig = {
      host => 'localhost',

Modified: addons/1.3/wxPOS-simple/WXPOS/Template/LaTeX.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Template/LaTeX.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/Template/LaTeX.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -55,7 +55,7 @@
 use strict;
 
 use Error qw(:try);
-use Template::Latex;
+use Template;
 
 #my $binmode = ':utf8';
 my $binmode = ':raw';
@@ -168,7 +168,7 @@
 	} elsif ($parent->{format_args}{filetype} eq 'pdf') {
 		$format = 'pdf';
 	}
-	$template = Template::Latex->new({
+	$template = Template->new({
 		LATEX_FORMAT => $format,
 		INCLUDE_PATH => [$parent->{include_path_lang}, $parent->{include_path},'templates/demo','UI/lib'],
 		START_TAG => quotemeta('<?lsmb'),
@@ -182,17 +182,18 @@
 		$source, 
 		{%$cleanvars,
 			'escape' => \&preprocess},
-		"$parent->{outputfile}.$format", {binmode => 1})) {
+		"$parent->{outputfile}.txt")) {
 		throw Error::Simple $template->error();
 	}
-	if (lc $format eq 'dvi') {
-		$parent->{mimetype} = 'application/x-dvi';
-	} elsif (lc $format eq 'pdf') {
-		$parent->{mimetype} = 'application/pdf';
-	} else {
-		$parent->{mimetype} = 'application/postscript';
-	}
-	$parent->{rendered} = "$parent->{outputfile}.$format";
+    chdir(${WXPOS::Sysconfig::tempdir});
+	# open (INV, '<', "$parent->{outputfile}.tex") || warn $@;
+	# open LPT, '>', 'LPT1';
+	# print LPT $_ while <INV>;
+	# close LPT;
+	# close INV;
+
+    system(qq|"notepad /p "$parent->{outputfile}.txt"|);
+	chdir("C:/Program Files/lsmb-wxpos");
 }
 
 sub postprocess {

Modified: addons/1.3/wxPOS-simple/WXPOS/Template.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/Template.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/Template.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -306,7 +306,7 @@
 
         for ( keys %args ) { $self->{output_args}->{$_} = $args{$_}; };
 
-	$self->_lpr_output($args->{printer});
+	$self->_lpr_output($args{printer});
 }
 
 sub _lpr_output {
@@ -319,7 +319,7 @@
 		}
                 $lpr->finalize if $lpr->can('finalize');
 	}
-	open (LPR, '|-', $lpr);
+	open (LPR, '|-', 'posprint.bat');
 
 	# Output is not defined here.  In the future we should consider
 	# changing this to use the system command and hit the file as an arg.

Modified: addons/1.3/wxPOS-simple/WXPOS/UI/AP.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI/AP.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/UI/AP.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -1,6 +1,9 @@
 package WXPOS::UI::AP;
 
-use Wx qw(wxDefaultPosition wxDefaultSize wxLI_HORIZONTAL wxCB_READONLY wxICON_ERROR wxOK wxCENTRE wxLC_REPORT wxLIST_NEXT_ALL wxLIST_STATE_SELECTED wxLIST_STATE_DONTCARE wxLIST_NEXT_BELOW wxLC_VIRTUAL);
+use Wx qw(wxDefaultPosition wxDefaultSize wxLI_HORIZONTAL wxCB_READONLY 
+          wxICON_ERROR wxOK wxCENTRE wxLC_REPORT wxLIST_NEXT_ALL 
+		  wxLIST_STATE_SELECTED wxLIST_STATE_DONTCARE wxLIST_NEXT_BELOW 
+		  wxLC_VIRTUAL wxCB_DROPDOWN wxCB_SIMPLE wxCB_SORT);
 use Wx::Event qw(EVT_BUTTON EVT_TEXT EVT_LISTBOX_DCLICK EVT_COMBOBOX EVT_LIST_ITEM_RIGHT_CLICK EVT_LIST_ITEM_SELECTED EVT_LIST_ITEM_DESELECTED);
 use base qw(Wx::Frame);
 use Wx::Grid;
@@ -66,17 +69,18 @@
 
 ### Line Entry
  $self->{part_numb} = Wx::ComboBox->new($self->{tab}, -1, '', 
-                                     [10, 460], [80, 24], $pnumlist);
+                                     [10, 460], [80, 24], $pnumlist, wxCB_SIMPLE | wxCB_SORT);
  EVT_TEXT($self->{tab}, $self->{part_numb}, 
           sub {$self->_autocomplete('part_numb', 
                                       [10, 460], [80, 24], $pnumlist)});
  $self->{desc} = Wx::ComboBox->new($self->{tab}, -1, '', 
-                                     [90, 460], [250, 24], $pdesclist);
+                                     [90, 460], [250, 24], $pdesclist, wxCB_SIMPLE | wxCB_SORT);
  EVT_TEXT($self->{tab}, $self->{desc}, 
           sub {$self->_autocomplete('desc', 
                                       [90, 460], [250,24], $pdesclist)});
  EVT_COMBOBOX($self->{tab}, $self->{desc}, sub { $self->_selectDesc } );
  my $parts_but = Wx::Button->new($self->{tab}, -1, 'Search', [440, 120], [60, 24]);
+ $parts_but->Show(0);
  EVT_BUTTON($self->{tab}, $parts_but, sub{$self->_listPartsByName});
  $self->{part_sellprice} 
      = Wx::TextCtrl->new($self->{tab}, -1, '', 
@@ -110,13 +114,13 @@
 
 ### Pay
  Wx::StaticLine->new($self->{tab}, -1, [0, 490], [800, 2], wxLI_HORIZONTAL);
- Wx::StaticText->new($self->{tab}, -1, 'Total: ', [0, 500], [90, 24]);
- $self->{net_total} = Wx::StaticText->new($self->{tab}, -1, '', [50, 500], [90, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Total: ', [350, 600], [90, 24]);
+ $self->{net_total} = Wx::StaticText->new($self->{tab}, -1, '', [400, 600], [90, 24]);
  $self->{net_total}->Show(0);
  $self->{tax_total} = Wx::StaticText->new($self->{tab}, -1, '', [200, 500], [90, 24]);
  $self->{tax_total}->Show(0);
- Wx::StaticText->new($self->{tab}, -1, 'Total: ', [0, 500], [90, 24]);
- $self->{total} = Wx::StaticText->new($self->{tab}, -1, '', [50, 500], [90, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Total: ', [350, 600], [90, 24]);
+ $self->{total} = Wx::StaticText->new($self->{tab}, -1, '', [400, 600], [90, 24]);
 ## pmt info
 
  my $paytypes = $WXPOS::Sysconfig::payment_types;
@@ -243,6 +247,7 @@
  $self->{tax_total}->SetLabel($self->{sesion}->{tk}->{ttax});
  $self->{total}->SetLabel($self->{sesion}->{tk}->{total});
  $self->{sesion}->{tk}->{items}++;
+  $self->calculate_total;
  return $part;
 }
 
@@ -250,23 +255,13 @@
 #
 sub _autocomplete {
     my ($self, $control, $place, $size, $list) = @_;
-    my $string = $self->{$control}->GetValue();
-    my $newlist = [];
-    push @$newlist, $_ for (grep /$string/, @$list);
-    $self->{$control}->Clear;
-   
-    $self->{$control}->Append($_) for @$newlist;
-    if ($control eq 'desc' and @$newlist 
-        and $string eq $newlist->[0]
-     ){
-        $self->{part_numb}->SetValue(
-             $pdescidx->{$string}->{partnumber});
-    }
+
 }
 
 sub _selectDesc {
     my ($self) = @_;
     my $val = $self->{desc}->GetString($self->{desc}->GetSelection);
+	$self->{part_numb}->SetValue($pdescidx->{$val}->{partnumber});
 }
 
 sub _selParts {
@@ -288,12 +283,10 @@
  $self->{sesion}->{tk}->{tnet} -= $sell;
  $self->{sesion}->{tk}->{ttax} -= $total_tax;
  $self->{sesion}->{tk}->{total} -= $total;
- $self->{net_total}->SetLabel($self->{sesion}->{tk}->{tnet});
- $self->{tax_total}->SetLabel($self->{sesion}->{tk}->{ttax});
- $self->{total}->SetLabel($self->{sesion}->{tk}->{total});
  $self->{list}->DeleteItem($item);
  $self->{sesion}->{tk}->{items}--;
  $self->{sel_del}->SetLabel($self->{list}->GetSelectedItemCount);
+  $self->calculate_total;
 #use Data::Dumper;
 #print Dumper($item_col);
  return 1;
@@ -324,8 +317,8 @@
 
 sub get_entity_credit_account {
     my ($self) = @_;
-    return $self->{customer_search}
-           ->{$self->{customer_list}->GetValue()};;
+    return $self->{vendor_search}
+           ->{$self->{vendor_list}->GetValue()};;
 }
 
 sub get_amounts {
@@ -346,14 +339,26 @@
     while (($item = $list->GetNextItem($item)) > -1){
         my $line = {};
         $line->{partnumber} = $list->GetItem($item, 0)->GetText(); 
+		$line->{description} = $list->GetItem($item, 1)->GetText();
         $line->{sellprice} = $list->GetItem($item, 2)->GetText();
         $line->{qty} =  $list->GetItem($item, 5)->GetText();
+		$line->{total} = $list->GetItem($item, 6)->GetText();
         push @$lines, $line;
     }
     
     return $lines; 
 }
 
+sub calculate_total {
+    my ($self) = @_;
+	my @lines = @{$self->get_lines};
+	my $total = 0;
+	for my $line (@lines){
+	     $total += $line->{total};
+    }
+	$self->{total}->SetLabel($total)
+}
+
 sub get_payments {
     my ($self) = @_;
     my $list = $self->{list};
@@ -369,10 +374,10 @@
 
 sub _Post {
     my ($self) = @_;
-    my $invoice = WXPOS::Invoice->from_UI($self, 2);
+    my $invoice = WXPOS::Invoice->from_UI($self, 1);
     try {
       $invoice->post;
-      $invoice->print(); # TODO
+      # $invoice->print(); # TODO
       # Ok, we succeeded, now to close the current tab and window, 
       # and initialize the next one.  -CT
     

Modified: addons/1.3/wxPOS-simple/WXPOS/UI/AR.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI/AR.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/UI/AR.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -1,6 +1,9 @@
 package WXPOS::UI::AR;
 
-use Wx qw(wxDefaultPosition wxDefaultSize wxLI_HORIZONTAL wxCB_READONLY wxICON_ERROR wxOK wxCENTRE wxLC_REPORT wxLIST_NEXT_ALL wxLIST_STATE_SELECTED wxLIST_STATE_DONTCARE wxLIST_NEXT_BELOW wxLC_VIRTUAL);
+use Wx qw(wxDefaultPosition wxDefaultSize wxLI_HORIZONTAL wxCB_READONLY 
+          wxICON_ERROR wxOK wxCENTRE wxLC_REPORT wxLIST_NEXT_ALL 
+		  wxLIST_STATE_SELECTED wxLIST_STATE_DONTCARE wxLIST_NEXT_BELOW 
+		  wxLC_VIRTUAL wxCB_DROPDOWN wxCB_SIMPLE wxCB_SORT);
 use Wx::Event qw(EVT_BUTTON EVT_TEXT EVT_LISTBOX_DCLICK EVT_COMBOBOX EVT_LIST_ITEM_RIGHT_CLICK EVT_LIST_ITEM_SELECTED EVT_LIST_ITEM_DESELECTED);
 use base qw(Wx::Frame);
 use Wx::Grid;
@@ -72,18 +75,19 @@
 
 ### Line Entry
  $self->{part_numb} = Wx::ComboBox->new($self->{tab}, -1, '', 
-                                     [10, 460], [80, 24], $pnumlist);
- EVT_TEXT($self->{tab}, $self->{part_numb}, 
-          sub {$self->_autocomplete('part_numb', 
-                                      [10, 460], [80, 24], $pnumlist)});
+                                     [10, 460], [80, 24], $pnumlist, wxCB_SIMPLE | wxCB_SORT);
+ #EVT_TEXT($self->{tab}, $self->{part_numb}, 
+ #         sub {$self->_autocomplete('part_numb', 
+ #                                     [10, 460], [80, 24], $pnumlist)});
  $self->{desc} = Wx::ComboBox->new($self->{tab}, -1, '', 
-                                     [90, 460], [250, 24], $pdesclist);
+                                     [90, 460], [250, 24], $pdesclist, wxCB_SIMPLE | wxCB_SORT);
  EVT_TEXT($self->{tab}, $self->{desc}, 
           sub {$self->_autocomplete('desc', 
                                       [90, 460], [250,24], $pdesclist)});
  EVT_COMBOBOX($self->{tab}, $self->{desc}, sub { $self->_selectDesc } );
  my $parts_but = Wx::Button->new($self->{tab}, -1, 'Search', [440, 120], [60, 24]);
  EVT_BUTTON($self->{tab}, $parts_but, sub{$self->_listPartsByName});
+ $parts_but->Show(0);
  $self->{part_sellprice} 
      = Wx::TextCtrl->new($self->{tab}, -1, '', 
                                      [350, 460], [90, 24]);
@@ -116,25 +120,25 @@
 
 ### Pay
  Wx::StaticLine->new($self->{tab}, -1, [0, 490], [800, 2], wxLI_HORIZONTAL);
- Wx::StaticText->new($self->{tab}, -1, 'Total: ', [0, 500], [90, 24]);
- $self->{net_total} = Wx::StaticText->new($self->{tab}, -1, '', [50, 500], [90, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Total: ', [350, 600], [90, 24]);
+ $self->{net_total} = Wx::StaticText->new($self->{tab}, -1, '', [400, 600], [90, 24]);
  $self->{net_total}->Show(0);
  $self->{tax_total} = Wx::StaticText->new($self->{tab}, -1, '', [200, 500], [90, 24]);
  $self->{tax_total}->Show(0);
- Wx::StaticText->new($self->{tab}, -1, 'Total: ', [0, 500], [90, 24]);
- $self->{total} = Wx::StaticText->new($self->{tab}, -1, '', [50, 500], [90, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Total: ', [350, 600], [90, 24]);
+ $self->{total} = Wx::StaticText->new($self->{tab}, -1, '', [400, 600], [90, 24]);
 ## pmt info
 
  my $paytypes = $WXPOS::Sysconfig::payment_types;
  $paytypes = [''] unless @$paytypes;
- Wx::StaticText->new($self->{WxPanel}, -1, 'Type', [150, 500], [80, 24]);
+ Wx::StaticText->new($self->{WxPanel}, -1, 'Type', [350, 500], [80, 24]);
  $self->{memo} = Wx::ComboBox->new($self->{tab}, -1, $paytypes->[0], 
-                              [200, 500], [75, 24], 
+                              [400, 500], [75, 24], 
                               $paytypes, wxCB_READONLY);
     
- Wx::StaticText->new($self->{tab}, -1, 'Source', [350, 500], [80, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Source', [350, 550], [80, 24]);
  $self->{source} = Wx::TextCtrl->new($self->{tab}, -1, '', 
-                                 [400, 500], [60, 24]
+                                 [400, 550], [60, 24]
  );
 
  my $invoice_post = Wx::Button->new($self->{tab}, -1, 'Pay', [700, 500], [90, 24]);
@@ -153,23 +157,23 @@
 #
 sub _autocomplete {
     my ($self, $control, $place, $size, $list) = @_;
-    my $string = $self->{$control}->GetValue();
-    my $newlist = [];
-    push @$newlist, $_ for (grep /$string/, @$list);
-    $self->{$control}->Clear;
-   
-    $self->{$control}->Append($_) for @$newlist;
-    if ($control eq 'desc' and @$newlist 
-        and $string eq $newlist->[0]
-     ){
-        $self->{part_numb}->SetValue(
-             $pdescidx->{$string}->{partnumber});
+
+}
+
+sub calculate_total {
+    my ($self) = @_;
+	my @lines = @{$self->get_lines};
+	my $total = 0;
+	for my $line (@lines){
+	     $total += $line->{total};
     }
+	$self->{total}->SetLabel($total)
 }
 
 sub _selectDesc {
     my ($self) = @_;
     my $val = $self->{desc}->GetString($self->{desc}->GetSelection);
+	$self->{part_numb}->SetValue($pdescidx->{$val}->{partnumber});
 }
 
 sub Customer {
@@ -278,7 +282,7 @@
  $self->{sesion}->{tk}->{total} += $self->format_money($total);
  $self->{net_total}->SetLabel($self->{sesion}->{tk}->{tnet});
  $self->{tax_total}->SetLabel($self->{sesion}->{tk}->{ttax});
- $self->{total}->SetLabel($self->{sesion}->{tk}->{total});
+ $self->calculate_total;
  $self->{sesion}->{tk}->{items}++;
  return $part;
 }
@@ -310,6 +314,7 @@
  $self->{sel_del}->SetLabel($self->{list}->GetSelectedItemCount);
 #use Data::Dumper;
 #print Dumper($item_col);
+ $self->calculate_total;
  return 1;
 }
 
@@ -360,8 +365,10 @@
     while (($item = $list->GetNextItem($item)) > -1){
         my $line = {};
         $line->{partnumber} = $list->GetItem($item, 0)->GetText(); 
+		$line->{description} = $list->GetItem($item, 1)->GetText();
         $line->{sellprice} = $list->GetItem($item, 2)->GetText();
         $line->{qty} =  $list->GetItem($item, 5)->GetText();
+		$line->{total} = $list->GetItem($item, 6)->GetText();
         push @$lines, $line;
     }
     

Added: addons/1.3/wxPOS-simple/WXPOS/UI/History.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI/History.pm	                        (rev 0)
+++ addons/1.3/wxPOS-simple/WXPOS/UI/History.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,162 @@
+=head1 NAME
+
+WXPOS::History - History report screen for WWXPOS
+
+=head1 SYNOPSIS
+
+This integrates through the menu, using standard interfaces
+
+=head1 METHODS
+
+=over
+
+=item new ($sesion, $action)
+
+This will get, set and go an action from the menu that is a method of this class. It will
+work as a kind of handler and will return a reference to that action.
+$sesion = It is a hash with all objects and variables needed.
+$action = Method name to invoque as String
+
+=item Parts ()
+
+This is an action that will show a panel asiking for number or description.
+
+=item _listPartsByName ()
+
+A private function used by the Search action that invoques lsmbdb interface to get parts list from the db.
+
+=back
+
+=head1 AUTHOR
+
+Andres Basile (..hidden..)
+
+=cut
+
+package WXPOS::UI::History;
+
+use base qw(Wx::Frame);
+use Wx::Event qw(EVT_BUTTON);
+use Wx qw(wxDefaultPosition wxDefaultSize wxMAXIMIZE wxCB_READONLY 
+       wxLC_REPORT wxLI_HORIZONTAL);
+use Wx::Grid;
+use WXPOS::Purchase_History;
+
+sub new {
+ my ($class, $sesion, $action) = @_;
+ my $self = {};
+ $self->{sesion} = $sesion;
+ bless $self, $class;
+ return $self->$action();
+}
+
+sub _close_pane {
+ my ($self) = $_;
+ my $selection = $WXPOS::State::Notebook->GetSelection;
+ $WXPOS::State::Notebook->DeletePage($selection);
+ return 1;
+}
+
+sub Report {
+ my ($self) = @_;
+ $self->{sesion}->{tk} = undef;
+ $self->{sesion}->{tk}->{items} = 0;
+ $self->{tab} = Wx::Panel->new($self->{sesion}->{nb}, -1, 
+                   wxDefaultPosition, wxDefaultSize);
+
+### Close Window Button
+ my $close_btn = Wx::Button->new($self->{tab}, -1, '[X]', [750, 3], [30, 24]);
+ EVT_BUTTON($self->{tab}, $close_btn, sub{$self->_close_pane});
+
+### Monthly Report
+ Wx::StaticText->new($self->{tab}, -1, 'Month', [10, 15], [30, 24]);
+ $self->{month} = Wx::TextCtrl->new($self->{tab}, -1, '', [50, 10], [50, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Year', [110, 15], [30, 24]);
+ $self->{year} = Wx::TextCtrl->new($self->{tab}, -1, '', [150, 10], [70, 24]);
+ my $monthly = Wx::Button->new($self->{tab}, -1, 'Monthly', [250, 10], [90, 24]);
+ EVT_BUTTON($self->{tab}, $monthly, sub{$self->_get_monthly});
+### History Search info
+ Wx::StaticLine->new($self->{tab}, -1, [0, 0], [800, 2], wxLI_HORIZONTAL);
+ Wx::StaticText->new($self->{tab}, -1, 'Description', [390, 15], [90, 24]);
+ $self->{description} = 
+       Wx::TextCtrl->new($self->{tab}, -1, '', [450, 10], [190, 24]);
+ my $search = Wx::Button->new($self->{tab}, -1, 'History', [650, 10], [90, 24]);
+ EVT_BUTTON($self->{tab}, $search , sub{$self->_get_history});
+#### Stock list
+ $self->{list} = Wx::ListCtrl->new($self->{tab}, -1, [5, 50], [750, 450], wxLC_REPORT);
+ $self->{list}->InsertColumn(1, 'Invoice', 0, 80);
+ $self->{list}->InsertColumn(2, 'Date', 0, 80);
+ $self->{list}->InsertColumn(3, 'SKU', 0, 80);
+ $self->{list}->InsertColumn(4, 'Description', 0, 200);
+ $self->{list}->InsertColumn(5, 'Qty', 0, 50);
+ $self->{list}->InsertColumn(6, 'Price', 0, 100),
+ $self->{list}->InsertColumn(7, 'Name', 0, 200);
+ $self->{description}->SetFocus();
+ $self->{listcount} = 0;
+ return $self->{tab};
+}
+
+sub _get_history {
+  my ($self) = @_;
+  $self->_reset_stocklist;
+  my $description = $self->{description}->GetValue;
+  $description = '' unless defined $description;
+  my $month = $self->{month}->GetValue;
+  $month ||= undef;
+  my $year = $self->{year}->GetValue;
+  $year ||= undef;
+  my @lines = WXPOS::Purchase_History->new(
+          month => $month,
+		  year => $year,
+          description => $description,
+  )->get_lines;
+  
+  warn scalar @lines;
+  # $self->{list}->DeleteItem(0) while $self->{list}->DeleteItem(0);
+  # $self->{listcount} = 0;
+  for my $item(@lines){
+    my $pp = $self->{list}->InsertStringItem($self->{listcount}, $item->{invnumber});
+    $self->{list}->SetItem($pp, 1, $item->{transdate}, -1);
+    $self->{list}->SetItem($pp, 2, $item->{partnumber}, -1);
+    $self->{list}->SetItem($pp, 3, $item->{description}, -1);
+    $self->{list}->SetItem($pp, 4, $item->{qty}, -1);
+	$self->{list}->SetItem($pp, 5, $item->{sellprice}, -1);
+	$self->{list}->SetItem($pp, 6, $item->{name}, -1);
+	++$self->{listitems};
+  }
+  
+}
+
+sub _reset_stocklist {
+ my ($self) = @_;
+ $self->{listitems} ||= 0;
+ return unless $self->{listitems};
+ $self->{list}->DeleteItem(0) for 0 .. $self->{listitems};
+ $self->{listcount} = 0;
+} 
+
+sub _get_monthly {
+  my ($self) = @_;
+  $self->_reset_stocklist;
+  my $month = $self->{month}->GetValue;
+  my $year = $self->{year}->GetValue;
+  $month ||= undef;
+  $year ||= undef;
+  my @lines = WXPOS::Purchase_History->call_dbmethod(
+      funcname => 'by_month', args => { month => $month, year => $year }
+  );
+  warn scalar @lines;
+
+  for my $item(@lines){
+    my $pp = $self->{list}->InsertStringItem($self->{listcount}, $item->{invnumber});
+    $self->{list}->SetItem($pp, 1, $item->{transdate}, -1);
+    $self->{list}->SetItem($pp, 2, $item->{partnumber}, -1);
+    $self->{list}->SetItem($pp, 3, $item->{description}, -1);
+    $self->{list}->SetItem($pp, 4, $item->{qty}, -1);
+	$self->{list}->SetItem($pp, 5, $item->{sellprice}, -1);
+	$self->{list}->SetItem($pp, 6, $item->{name}, -1);
+	++$self->{listitems};
+  }
+}
+
+1;

Modified: addons/1.3/wxPOS-simple/WXPOS/UI/IC.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI/IC.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/UI/IC.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -37,16 +37,16 @@
 
 use base qw(Wx::Frame);
 use Wx::Event qw(EVT_BUTTON);
-use Wx qw(wxDefaultPosition wxDefaultSize wxMAXIMIZE wxCB_READONLY);
+use Wx qw(wxDefaultPosition wxDefaultSize wxMAXIMIZE wxCB_READONLY 
+       wxLC_REPORT wxLI_HORIZONTAL);
 use Wx::Grid;
+use WXPOS::Stocklist;
 
 sub new {
  my ($class, $sesion, $action) = @_;
  my $self = {};
  $self->{sesion} = $sesion;
- $self->{wh_dft_id} = $self->{sesion}->{defaults}->{wh};
  bless $self, $class;
- $self->_getWarehouses();
  return $self->$action();
 }
 
@@ -57,60 +57,55 @@
  return 1;
 }
 
-sub _getWarehouses {
+sub Stocklist {
  my ($self) = @_;
- $self->{wh_des}->{''} = '';
- foreach (@{$self->{sesion}->{ldb}->getWarehouseList()}) {
-  $self->{wh_des}->{$_->[1]} = $_->[0];
-  if ($_->[0] == $self->{wh_dft_id}) {
-   $self->{wh_dft_des} = $_->[1];
-  }
- }
- return $self;
-}
+ $self->{sesion}->{tk} = undef;
+ $self->{sesion}->{tk}->{items} = 0;
+ $self->{tab} = Wx::Panel->new($self->{sesion}->{nb}, -1, 
+                   wxDefaultPosition, wxDefaultSize);
 
-sub Parts {
- my ($self) = @_;
-### Close Window
- $self->{WxPanel} = Wx::Panel->new($self->{sesion}->{nb}, -1, wxDefaultPosition, wxDefaultSize, wxMAXIMIZE);
- my $close_btn = Wx::Button->new($self->{WxPanel}, -1, '[X]', [750, 3], [30, 24]);
- EVT_BUTTON($self->{WxPanel}, $close_btn, sub{$self->_close_pane});
- Wx::StaticText->new($self->{WxPanel}, -1, 'Number', [10, 20], [90, 24]);
- $self->{numb} = Wx::TextCtrl->new($self->{WxPanel}, -1, '', [110, 20], [90, 24]);
- Wx::StaticText->new($self->{WxPanel}, -1, 'Description', [10, 60], [90, 24]);
- $self->{desc} = Wx::TextCtrl->new($self->{WxPanel}, -1, '', [110, 60], [180, 24]);
- Wx::StaticText->new($self->{WxPanel}, -1, 'Warehouse', [310, 40], [90, 24]);
- $self->{wh} = Wx::ComboBox->new($self->{WxPanel}, -1, $self->{wh_dft_des}, [400, 40], [180, 24], [keys(%{$self->{wh_des}})]);
- my $button = Wx::Button->new($self->{WxPanel}, -1, 'Search', [110, 100], [60, 24]);
- EVT_BUTTON($self->{WxPanel}, $button, sub{$self->_listPartsByName});
- return $self->{WxPanel};
+### Close Window Button
+ my $close_btn = Wx::Button->new($self->{tab}, -1, '[X]', [750, 3], [30, 24]);
+ EVT_BUTTON($self->{tab}, $close_btn, sub{$self->_close_pane});
+
+### Parts info
+ Wx::StaticLine->new($self->{tab}, -1, [0, 0], [800, 2], wxLI_HORIZONTAL);
+ Wx::StaticText->new($self->{tab}, -1, 'Partnumber', [10, 10], [90, 24]);
+ $self->{partnumber} = 
+       Wx::TextCtrl->new($self->{tab}, -1, '', [110, 10], [90, 24]);
+ Wx::StaticText->new($self->{tab}, -1, 'Description', [210, 10], [90, 24]);
+ $self->{description} = 
+       Wx::TextCtrl->new($self->{tab}, -1, '', [310, 10], [190, 24]);
+ my $search = Wx::Button->new($self->{tab}, -1, 'Search', [510, 10], [90, 24]);
+ EVT_BUTTON($self->{tab}, $search , sub{$self->_get_stocklist});
+#### Stock list
+ $self->{list} = Wx::ListCtrl->new($self->{tab}, -1, [5, 50], [750, 450], wxLC_REPORT);
+ $self->{list}->InsertColumn(1, 'ID', 0, 80);
+ $self->{list}->InsertColumn(2, 'Number', 0, 80);
+ $self->{list}->InsertColumn(3, 'Description', 0, 250);
+ $self->{list}->InsertColumn(4, 'Price', 0, 100);
+ $self->{list}->InsertColumn(5, 'Onhand', 0, 100);
+ $self->{partnumber}->SetFocus();
+ $self->{listcount} = 0;
+ return $self->{tab};
 }
 
-sub _listPartsByName {
- my($self, $event) = @_;
- my $numb = $self->{numb}->GetValue();
- my $desc = $self->{desc}->GetValue();
- my $wh = $self->{wh_des}->{$self->{wh}->GetValue()};wxCB_READONLY
- $self->{list} = Wx::Grid->new($self->{WxPanel}, -1, [10, 160], [790, 480], wxCB_READONLY);
- $self->{list}->CreateGrid(0, 4);
- $self->{list}->SetColLabelValue(0, 'Number');
- $self->{list}->SetColSize(0, 100);
- $self->{list}->SetColLabelValue(1, 'Description');
- $self->{list}->SetColSize(1, 440);
- $self->{list}->SetColLabelValue(2, 'Warehouse');
- $self->{list}->SetColSize(2, 100);
- $self->{list}->SetColLabelValue(3, 'Qty');
- $self->{list}->SetColSize(3, 60);
- my $list = $self->{sesion}->{ldb}->getPartsList($numb, $desc, $wh);
- my $i = 0;
- foreach (@{$list}) {
-  $self->{list}->AppendRows();
-  $self->{list}->SetCellValue($i, 0, $_->[0]);
-  $self->{list}->SetCellValue($i, 1, $_->[1]);
-  $self->{list}->SetCellValue($i, 2, $_->[2]);
-  $self->{list}->SetCellValue($i, 3, $_->[3]);
-  $i++;
- }
- return $self->{list};
-}
+sub _get_stocklist {
+  my ($self) = @_;
+  my @stocklist = WXPOS::Stocklist->search(
+          $self->{partnumber}->GetValue,
+          $self->{description}->GetValue
+  );
+  # $self->{list}->DeleteItem(0) while $self->{list}->DeleteItem(0);
+  # $self->{listcount} = 0;
+  for my $item(@stocklist){
+    my $pp = $self->{list}->InsertStringItem($self->{listcount}, $item->id);
+    $self->{list}->SetItem($pp, 1, $item->partnumber, -1);
+    $self->{list}->SetItem($pp, 2, $item->description, -1);
+    $self->{list}->SetItem($pp, 3, $item->sellprice, -1);
+    $self->{list}->SetItem($pp, 4, $item->onhand, -1);
+  }
+  warn scalar @stocklist;
+} 
+
 1;

Modified: addons/1.3/wxPOS-simple/WXPOS/UI/Login.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI/Login.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/UI/Login.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -40,7 +40,7 @@
 
 sub new {
  my ($class) = @_;
- my $self = Wx::Dialog->new(undef , -1, "LedgerSMB", wxDefaultPosition, [300, 320]);
+ my $self = Wx::Dialog->new(undef , -1, "LedgerSMB", wxDefaultPosition, [300, 350]);
  bless $self, $class;
  $self->{WxPanel} = Wx::Panel->new($self, -1, wxDefaultPosition, [300, 320]);
  Wx::InitAllImageHandlers();

Modified: addons/1.3/wxPOS-simple/WXPOS/UI.pm
===================================================================
--- addons/1.3/wxPOS-simple/WXPOS/UI.pm	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/WXPOS/UI.pm	2014-03-07 05:12:58 UTC (rev 6927)
@@ -81,7 +81,9 @@
 
 ### Menu
 # TODO: It should be loaded/created on demand according to user acl.
- my($ID_FILE, $ID_ABOUT, $ID_EXIT, $ID_AR, $AR_INVOICE, $AR_TRANSACTION, $AR_CUSTOMER, $ID_AP, $ID_IC, $IC_PARTS, $AP_INVOICE) = (100 .. 200);
+ my($ID_FILE, $ID_ABOUT, $ID_EXIT, $ID_AR, $AR_INVOICE, $AR_TRANSACTION, 
+    $AR_CUSTOMER, $ID_AP, $ID_IC, $IC_PARTS, $AP_INVOICE, $SALES_HIST) 
+	= (100 .. 200);
  my $bar = Wx::MenuBar->new;
 
  my $file = Wx::Menu->new;
@@ -96,17 +98,19 @@
  EVT_MENU($self, $AR_INVOICE, sub{$self->_load_module(AR, Invoice)});
  $ar->Append($AR_CUSTOMER, "&Customer");
  EVT_MENU($self, $AR_CUSTOMER, sub{$self->_load_module(Contact, Customer)});
+ $ar->Append($SALES_HIST, '&History');
+ EVT_MENU($self, $SALES_HIST, sub{$self->_load_module(History, Report)});
  $bar->Append($ar, "&Sales" );
 
-# my $ic = Wx::Menu->new;
-# $ic->Append($IC_PARTS, "&Parts");
-# EVT_MENU($self, $IC_PARTS, sub{$self->_load_module(IC, Parts)});
-# $bar->Append($ic, "&Inventory" );
  my $ap = Wx::Menu->new;
  $ap->Append($AP_INVOICE, "&Purchase");
  EVT_MENU($self, $AP_INVOICE, sub{$self->_load_module('AP', 'Purchase')}); 
  $bar->Append($ap, "&Purchases" );
 
+ my $ic = Wx::Menu->new;
+ $ic->Append($IC_PARTS, "&Stock List");
+ EVT_MENU($self, $IC_PARTS, sub{$self->_load_module('IC', 'Stocklist')});
+ $bar->Append($ic, "&Inventory" );
  $self->SetMenuBar($bar);
  return $self;
 }

Added: addons/1.3/wxPOS-simple/setup/Parts.sql
===================================================================
--- addons/1.3/wxPOS-simple/setup/Parts.sql	                        (rev 0)
+++ addons/1.3/wxPOS-simple/setup/Parts.sql	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,30 @@
+DROP VIEW IF EXISTS stocklist CASCADE;
+
+CREATE VIEW stocklist AS 
+   SELECT p.id, p.partnumber, p.description, p.sellprice, 
+          sum(i.qty) * -1 as onhand
+     FROM parts p
+LEFT JOIN invoice i ON p.id = i.parts_id
+    WHERE not p.obsolete
+ GROUP BY p.id, p.partnumber, p.description, p.sellprice
+ ORDER BY p.partnumber
+;
+
+GRANT SELECT ON stocklist TO PUBLIC;
+
+CREATE OR REPLACE FUNCTION stocklist__search
+(in_partnumber text, in_description text)
+RETURNS SETOF stocklist LANGUAGE SQL AS 
+$$
+SELECT * FROM stocklist 
+ WHERE partnumber like '%' || $1 || '%'
+       AND description like '%' || $2 || '%';
+$$;
+
+CREATE OR REPLACE FUNCTION stocklist__set_price
+(in_id int, in_sellprice numeric)
+RETURNS stocklist LANGUAGE SQL AS
+$$
+UPDATE parts SET sellprice = $2 WHERE id = $1;
+SELECT * FROM stocklist WHERE id = $1;
+$$;

Modified: addons/1.3/wxPOS-simple/setup/functions.sql
===================================================================
--- addons/1.3/wxPOS-simple/setup/functions.sql	2014-03-06 09:34:34 UTC (rev 6926)
+++ addons/1.3/wxPOS-simple/setup/functions.sql	2014-03-07 05:12:58 UTC (rev 6927)
@@ -98,6 +98,7 @@
 SELECT * FROM parts 
  WHERE EXISTS (select 1 FROM defaults 
                 WHERE setting_key = 'wxpos_autocomplete_parts' AND value = '1')
+        AND NOT OBSOLETE
  ORDER BY partnumber;
 $$;
 

Added: addons/1.3/wxPOS-simple/setup/purchase_history.sql
===================================================================
--- addons/1.3/wxPOS-simple/setup/purchase_history.sql	                        (rev 0)
+++ addons/1.3/wxPOS-simple/setup/purchase_history.sql	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,61 @@
+BEGIN;
+
+
+CREATE OR REPLACE FUNCTION first_of_month (in_month int, in_year int)
+RETURNS DATE LANGUAGE SQL AS
+$$ SELECT ($2::text || '-' ||  $1::text || '-01')::date $$; 
+
+
+CREATE OR REPLACE VIEW purchase_history AS 
+ SELECT a.transdate, 
+    a.invnumber, 
+    p.partnumber, 
+    p.description, 
+    i.qty, 
+    i.sellprice, 
+    e.name
+   FROM ar a
+   JOIN invoice i ON a.id = i.trans_id
+   JOIN entity_credit_account eca ON eca.id = a.entity_credit_account
+   JOIN entity e ON eca.entity_id = e.id
+   JOIN parts p ON p.id = i.parts_id
+  ORDER BY a.transdate, a.invnumber;
+
+ALTER TABLE purchase_history
+  OWNER TO postgres;
+GRANT ALL ON TABLE purchase_history TO postgres;
+GRANT SELECT ON TABLE purchase_history TO public;
+
+Drop function if exists purchase_history__search
+(in_date_from date, in_date_to date);
+
+DROP FUNCTION IF EXISTS purchase_history__search
+(date, date, text);
+
+CREATE OR REPLACE FUNCTION purchase_history__search
+(in_month int, in_year int, in_description text)
+RETURNS SETOF purchase_history LANGUAGE SQL AS
+$$
+SELECT * FROM purchase_history 
+ WHERE (transdate BETWEEN first_of_month($1, $2) 
+                     AND first_of_month($1, $2) + '1 month'::interval 
+					                            - '1 day'::interval
+		OR $1 IS NULL or $2 is null)
+        AND (extract('year' from transdate) = $2 OR $2 is null) 		
+		AND description ilike '%' || $3 || '%'
+		AND name not like 'Inventory%';
+$$;
+
+
+CREATE OR REPLACE FUNCTION purchase_history__by_month
+(in_month int, in_year int)
+RETURNS SETOF purchase_history
+LANGUAGE SQL AS $$
+SELECT transdate, null::text, partnumber, description, 
+       sum(qty) as qty, sum(qty * sellprice), null::text
+  FROM purchase_history WHERE name not like 'INVENTORY%'
+       and date_trunc('month', transdate) = ($2::text || '-' || $1::text || '-01')::date
+ GROUP BY transdate, partnumber, description
+ ORDER BY transdate desc, description desc;
+$$; 
+COMMIT;
\ No newline at end of file

Added: addons/1.3/wxPOS-simple/templates/invoice.tex
===================================================================
--- addons/1.3/wxPOS-simple/templates/invoice.tex	                        (rev 0)
+++ addons/1.3/wxPOS-simple/templates/invoice.tex	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,29 @@
+
+
+          <?lsmb "GRACIA PETSTORE" FILTER format('%37.33s') ?>
+          <?lsmb "Show your love with the best quality" FILTER format('%49.49s') ?>
+          <?lsmb "Ruko Gracia No. 19, Graha Raya - Bintaro" FILTER format('%50.60s') ?>
+          <?lsmb "Telp: (021) 2931 4504, 9228 3191" FILTER format('%47.47s') ?>
+
+		  
+          Invoice/Faktur: <?lsmb invnumber ?>                              Date: <?lsmb printdate ?>
+		  
+
+          Qty   Description                 Unit        SKU             Amount
+<?lsmb FOREACH line IN invoice_lines ?>
+        <?lsmb line.qty FILTER format('%5.5s') ?>   <?lsmb 
+            line.description FILTER format('%-21.21s') ?> <?lsmb 
+            line.sellprice FILTER format('%14.14s') ?>    <?lsmb 
+             line.partnumber FILTER format('%-10.10s') ?>      <?lsmb line.total FILTER format('%-12.12s') ?>
+<?lsmb- END # invoice_lines ?>
+
+
+                            
+                                                              Subtotal: <?lsmb amount FILTER format('%-12.12s') ?>
+
+
+
+
+   Thank you for your valued business!
+
+

Added: addons/1.3/wxPOS-simple/templates/invoice.txt
===================================================================
--- addons/1.3/wxPOS-simple/templates/invoice.txt	                        (rev 0)
+++ addons/1.3/wxPOS-simple/templates/invoice.txt	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,25 @@
+          <?lsmb "GRACIA PETSTORE" FILTER format('%33.33s') ?>
+          <?lsmb "Show your love with the best quality" FILTER format('%22.22s') ?>
+          <?lsmb "Ruko Gracia No. 19, Graha Raya - Bintaro" FILTER format('%20.20s') ?>
+          <?lsmb "Telp: (021) 2931 4504, 9228 3191" FILTER format('%23.23s') ?>
+
+          Inv #/Date: <?lsmb invnumber ?> / <?lsmb printdate ?>
+
+            Qty Description                    Amount    SKU     Unit Price
+<?lsmb FOREACH line IN invoice_lines ?>
+          <?lsmb line.qty FILTER format('%5.5s') ?>       <?lsmb 
+            description.loop_count FILTER format('%-18.18s') ?> <?lsmb 
+            linetotal.loop_count FILTER format('%14.14s') ?> <?lsmb 
+             line.partnumber FILTER format('%-8.8s') ?> <?lsmb line.sellprice FILTER format(%-12.12s') ?>
+<?lsmb END # invoice_lines ?>
+
+
+                            ------------
+                     Subtotal: <?lsmb amount FILTER format('%9.9s') ?>
+<?lsmb END # taxincluded ?>
+
+
+
+   Thank you for your valued business!
+
+

Added: addons/1.3/wxPOS-simple/templates/letterhead.tex
===================================================================
--- addons/1.3/wxPOS-simple/templates/letterhead.tex	                        (rev 0)
+++ addons/1.3/wxPOS-simple/templates/letterhead.tex	2014-03-07 05:12:58 UTC (rev 6927)
@@ -0,0 +1,17 @@
+
+\begin{minipage}{1.5in}
+\includegraphics{/logos/LOGO_GRACIA} 
+\end{minipage}
+\begin{minipage}{6in}
+{\Huge GRACIA PETSTORE}\\
+Show your love with the best quality\\
+Ruko Gracia No 19 Graha Raya --- Bintaro\\
+Telp: (021) 2931 4504, 9228 3191\\
+\end{minipage}\\
+ \includegraphics[scale=0.15]{c:/logos/logo_fortan} \hspace{10em}
+   \includegraphics[scale=0.30]{c:/logos/logo_schweikert}\hspace{10em}
+   \includegraphics[scale=0.10]{c:/logos/Meradog_Logo-2011}
+
+
+
+  \rule[1.5em]{\textwidth}{0.5pt}

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


------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
_______________________________________________
Ledger-smb-commits mailing list
..hidden..
https://lists.sourceforge.net/lists/listinfo/ledger-smb-commits