Merge branch 'constraints_in_tax_and_taxkeys'
authorNiclas Zimmermann <niclas@kivitendo-premium.de>
Fri, 22 Feb 2013 12:44:09 +0000 (13:44 +0100)
committerNiclas Zimmermann <niclas@kivitendo-premium.de>
Fri, 22 Feb 2013 12:44:09 +0000 (13:44 +0100)
SL/DB/MetaSetup/PeriodicInvoicesConfig.pm
SL/DB/PeriodicInvoicesConfig.pm
SL/SEPA.pm
SL/Template/OpenDocument.pm
css/kivitendo/jquery-ui.custom.css
css/lx-office-erp/jquery-ui.custom.css
image/map.png [new file with mode: 0644]
locale/de/all
scripts/console
scripts/rose_auto_create_model.pl
templates/webpages/ct/form_header.html

index aeaf1c2..8860e8c 100644 (file)
@@ -32,7 +32,7 @@ __PACKAGE__->meta->setup(
       key_columns => { ar_chart_id => 'id' },
     },
 
-    oe => {
+    order => {
       class       => 'SL::DB::Order',
       key_columns => { oe_id => 'id' },
     },
index c9ef222..2b4542a 100644 (file)
@@ -4,16 +4,6 @@ use strict;
 
 use SL::DB::MetaSetup::PeriodicInvoicesConfig;
 
-__PACKAGE__->meta->add_relationships(
-  order        => {
-    type       => 'many to one',
-    class      => 'SL::DB::Order',
-    column_map => { oe_id => 'id' },
-  },
-);
-
-__PACKAGE__->meta->initialize;
-
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
 __PACKAGE__->meta->make_manager_class;
 
index e07fdca..ea35312 100644 (file)
@@ -357,8 +357,8 @@ sub post_payment {
                                AND ((c.link LIKE '%:${ARAP}') OR (c.link LIKE '${ARAP}:%') OR (c.link = '${ARAP}'))
                              LIMIT 1| ],
 
-    'add_acc_trans'  => [ qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate,       source, memo)
-                             VALUES                (?,        ?,        ?,      ?,         current_date, ?,      '')| ],
+    'add_acc_trans'  => [ qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate,       source, memo, taxkey, tax_id)
+                             VALUES                (?,        ?,        ?,      ?,         current_date, ?,      '',   0,      (SELECT id FROM tax WHERE taxkey=0 LIMIT 1))| ],
 
     'update_arap'    => [ qq|UPDATE ${arap}
                              SET paid = paid + ?
index e0523d3..f9507f9 100644 (file)
@@ -457,10 +457,19 @@ sub spawn_openoffice {
       last;
     }
 
+    if ($::dispatcher->interface_type eq 'FastCGI') {
+      $::dispatcher->{request}->Detach;
+    }
+
     if (!$spawned_oo) {
       my $pid = fork();
       if (0 == $pid) {
         $main::lxdebug->message(LXDebug->DEBUG2(), "  Child daemonizing\n");
+
+        if ($::dispatcher->interface_type eq 'FastCGI') {
+          $::dispatcher->{request}->Finish;
+          $::dispatcher->{request}->LastCall;
+        }
         chdir('/');
         open(STDIN, '/dev/null');
         open(STDOUT, '>/dev/null');
@@ -474,6 +483,11 @@ sub spawn_openoffice {
                        "-accept=socket,host=localhost,port=" .
                        $::lx_office_conf{print_templates}->{openofficeorg_daemon_port} . ";urp;");
         exec(@cmdline);
+      } else {
+        # parent
+        if ($::dispatcher->interface_type eq 'FastCGI') {
+          $::dispatcher->{request}->Attach;
+        }
       }
 
       $main::lxdebug->message(LXDebug->DEBUG2(), "  Parent after fork\n");
index e9dae4f..e5e6f29 100644 (file)
@@ -9,6 +9,7 @@
   color: #333333;
   font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
   font-size: 1.1em;
+  overflow: hidden;
 }
 
 .tabwidget ul {
index e4c151c..c9559f2 100644 (file)
@@ -9,6 +9,7 @@
   color: #000000;
   font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
   font-size: 1.1em;
+  overflow: hidden;
 }
 
 .tabwidget ul {
diff --git a/image/map.png b/image/map.png
new file mode 100644 (file)
index 0000000..ac32c96
Binary files /dev/null and b/image/map.png differ
index 2c4423b..d9548a5 100644 (file)
@@ -1159,6 +1159,7 @@ $self->{texts} = {
   'Manage Custom Variables'     => 'Benutzerdefinierte Variablen',
   'Mandantennummer'             => 'Mandantennummer',
   'Mandatory Departments'       => 'Benutzer muss Abteilungen vergeben',
+  'Map'                         => 'Karte',
   'Mar'                         => 'März',
   'March'                       => 'März',
   'Margepercent'                => 'Ertrag prozentual',
index 239ed54..d264a89 100755 (executable)
@@ -48,6 +48,7 @@ use SL::InstanceConfiguration;
 use SL::Locale;
 use SL::LXDebug;
 use Data::Dumper;
+use List::Util qw(max);
 
 # this is a cleaned up version of am.pl
 # it lacks redirection, some html setup and most of the authentication process.
@@ -129,6 +130,43 @@ sub pp {
   Data::Dumper::Dumper(@_);
 }
 
+sub ptab {
+  my @rows = ref($_[0]) eq 'ARRAY' ? @{ $_[0] } : @_;
+  return '<empty result set>' unless @rows;
+
+  my @columns = sort keys %{ $rows[0] };
+  my @widths  = map { max @{ $_ } } map { my $column = $_; [ length($column), map { length("" . ($_->{$column} // '')) } @rows ] } @columns;
+  my @output  = (join ' | ', map { my $width = $widths[$_]; sprintf "\%-${width}s", $columns[$_] } (0..@columns - 1));
+  push @output, join('-+-', map { '-' x $_ } @widths);
+  push @output, map { my $row = $_; join(' | ', map { my $width = $widths[$_]; sprintf "\%-${width}s", $row->{ $columns[$_] } // '' } (0..@columns - 1) ) } @rows;
+
+  return join("\n", @output);
+}
+
+sub pobj {
+  my ($obj) = @_;
+  return '<no object>' unless $obj;
+
+  my $ref        =  ref $obj;
+  $ref           =~ s/^SL::DB:://;
+  my %primaries  =  map { ($_ => 1) } $obj->meta->primary_key;
+  my @columns    =  map { "${_}:" . ($obj->$_ // 'UNDEF') } sort $obj->meta->primary_key;
+  push @columns,    map { "${_}:" . ($obj->$_ // 'UNDEF') } grep { !$primaries{$_} } sort map { $_->{name} } $obj->meta->columns;
+
+  return "<${ref} " . join(' ', @columns) . '>';
+}
+
+sub sql {
+  my $dbh            = ref($_[0]) ? shift : $::form->get_standard_dbh;
+  my ($query, @args) = @_;
+
+  if ($query =~ m/^\s*select/i) {
+    ptab($dbh->selectall_arrayref($query, { Slice => {} }, @args));
+  } else {
+    $dbh->do($query, { Slice => {} }, @args);
+  }
+}
+
 1;
 
 __END__
@@ -165,6 +203,47 @@ Currently C<pp> will set the Data::Dumper depth to 2, so if you need a
 different depth, you'll have to change that. A nice feature would be to
 configure that, or at least to be able to change it at runtime.
 
+=head2 ptab C<@data>
+
+Returns a tabular representation of C<@data>. C<@data> must be an
+array or array reference containing hash references. Column widths are
+calculated automatically.
+
+Undefined values are represented by an empty column.
+
+Example usage:
+
+    ptab($dbh->selectall_arrayref("SELECT * FROM employee", { Slice => {} }));
+
+=head2 pobj C<$obj>
+
+Returns a textual representation of the L<Rose::DB> instance
+C<$obj>. This includes the class name, then the primary key columns as
+name/value pairs and then all other columns as name/value pairs.
+
+Undefined values are represented by C<UNDEF>.
+
+Example usage:
+
+    pobj(SL::DB::Manager::Employee->find_by(login => 'demo'));
+
+=head2 sql C<[ $dbh, ] $query, @bind_values>
+
+Executes an SQL query using the optional bind values. If the first
+parameter is a database handle then that database handle is used;
+otherwise the handle returned by L<SL::Form/get_standard_dbh> is used.
+
+If the query is a C<SELECT> then the result is filtered through
+L<ptab()>. Otherwise the result of C<$dbh-&gt;do($query, undef, @bind_values)>
+is returned.
+
+Example usage:
+
+    sql(qq|SELECT * FROM employee|);
+    sql(SL::DB::Employee->new->db->dbh,
+        qq|UPDATE employee SET notes = ? WHERE login = ?|,
+        'This guy is evil!', 'demo');
+
 =head2 lxinit C<login>
 
 Login into lx-office using a specified login. No password will be required, and
index 20048f2..7aab083 100755 (executable)
@@ -52,6 +52,8 @@ our %foreign_key_name_map = (
   orderitems           => { parts => 'part', trans => 'order', },
   delivery_order_items => { parts => 'part' },
   invoice              => { parts => 'part' },
+
+  periodic_invoices_configs => { oe => 'order' },
 );
 
 sub setup {
index d769b04..f56c9c2 100644 (file)
 
      <tr>
       <th align="right" nowrap>[% 'Street' | $T8 %]</th>
-      <td><input name="street" size="35" maxlength="75" value="[% HTML.escape(street) %]"></td>
+      <td>
+        <input name="street" size="35" maxlength="75" value="[% HTML.escape(street) %]">
+        <a
+          href="#"
+          onclick="window.open('https://maps.google.com/maps?q='+ encodeURIComponent($('#billing input[name=street]').val() +', '+ $('#billing input[name=zipcode]').val() +' '+ $('#billing input[name=city]').val() +', '+ $('#billing input[name=country]').val()), '_blank'); window.focus();"
+          title="[% 'Map' | $T8 %]"
+          >
+            <img src="image/map.png" alt="[% 'Map' | $T8 %]" />
+          </a>
+      </td>
      </tr>
 
      <tr>