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

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



Revision: 6928
          http://sourceforge.net/p/ledger-smb/code/6928
Author:   einhverfr
Date:     2014-03-07 05:21:14 +0000 (Fri, 07 Mar 2014)
Log Message:
-----------
Merging fixes and new reports back into wxpos main

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

Added Paths:
-----------
    addons/1.3/wxPOS/setup/purchase_history.sql
    addons/1.3/wxPOS/templates/

Modified: addons/1.3/wxPOS/WXPOS/Invoice.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/Invoice.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/Invoice.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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/WXPOS/Part.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/Part.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/Part.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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;
 }
 

Modified: addons/1.3/wxPOS/WXPOS/Sysconfig.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/Sysconfig.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/Sysconfig.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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/WXPOS/Template/LaTeX.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/Template/LaTeX.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/Template/LaTeX.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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/WXPOS/Template.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/Template.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/Template.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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/WXPOS/UI/AP.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/UI/AP.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/UI/AP.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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;
@@ -65,17 +68,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, '', 
@@ -227,6 +231,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;
 }
 
@@ -234,23 +239,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 {
@@ -272,12 +267,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;

Modified: addons/1.3/wxPOS/WXPOS/UI/AR.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/UI/AR.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/UI/AR.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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;
@@ -71,18 +74,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]);
@@ -137,23 +141,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 {
@@ -262,7 +266,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;
 }
@@ -294,6 +298,7 @@
  $self->{sel_del}->SetLabel($self->{list}->GetSelectedItemCount);
 #use Data::Dumper;
 #print Dumper($item_col);
+ $self->calculate_total;
  return 1;
 }
 

Modified: addons/1.3/wxPOS/WXPOS/UI/IC.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/UI/IC.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/UI/IC.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -96,6 +96,8 @@
           $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);

Modified: addons/1.3/wxPOS/WXPOS/UI/Login.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/UI/Login.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/UI/Login.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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/WXPOS/UI.pm
===================================================================
--- addons/1.3/wxPOS/WXPOS/UI.pm	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/WXPOS/UI.pm	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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,6 +98,8 @@
  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 $ap = Wx::Menu->new;

Modified: addons/1.3/wxPOS/setup/functions.sql
===================================================================
--- addons/1.3/wxPOS/setup/functions.sql	2014-03-07 05:12:58 UTC (rev 6927)
+++ addons/1.3/wxPOS/setup/functions.sql	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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;
 $$;
 

Copied: addons/1.3/wxPOS/setup/purchase_history.sql (from rev 6927, addons/1.3/wxPOS-simple/setup/purchase_history.sql)
===================================================================
--- addons/1.3/wxPOS/setup/purchase_history.sql	                        (rev 0)
+++ addons/1.3/wxPOS/setup/purchase_history.sql	2014-03-07 05:21:14 UTC (rev 6928)
@@ -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

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