WebshopApi: Shop Controller
authorWerner Hahn <wh@futureworldsearch.net>
Fri, 22 Sep 2017 00:25:37 +0000 (02:25 +0200)
committerWerner Hahn <wh@futureworldsearch.net>
Tue, 26 Sep 2017 10:25:02 +0000 (12:25 +0200)
SL/Controller/Shop.pm [new file with mode: 0644]
js/kivi.Shop.js [new file with mode: 0644]
templates/webpages/shops/form.html [new file with mode: 0644]
templates/webpages/shops/list.html [new file with mode: 0644]
templates/webpages/shops/test_shop_connection.html [new file with mode: 0644]

diff --git a/SL/Controller/Shop.pm b/SL/Controller/Shop.pm
new file mode 100644 (file)
index 0000000..afc7662
--- /dev/null
@@ -0,0 +1,213 @@
+package SL::Controller::Shop;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use SL::Helper::Flash;
+use SL::Locale::String;
+use SL::DB::Default;
+use SL::DB::Manager::Shop;
+use SL::DB::Pricegroup;
+use SL::DB::TaxZone;
+
+use Rose::Object::MakeMethods::Generic (
+  scalar                  => [ qw(connectors price_types price_sources taxzone_id protocols) ],
+  'scalar --get_set_init' => [ qw(shop) ]
+);
+
+__PACKAGE__->run_before('check_auth');
+__PACKAGE__->run_before('load_types',    only => [ qw(new edit) ]);
+
+#
+# actions
+#
+
+sub action_list {
+  my ($self) = @_;
+
+  $self->_setup_list_action_bar;
+  $self->render('shops/list',
+                title => t8('Shops'),
+                SHOPS => SL::DB::Manager::Shop->get_all_sorted,
+               );
+}
+
+sub action_edit {
+  my ($self) = @_;
+
+  my $is_new = !$self->shop->id;
+  $self->_setup_form_action_bar;
+  $self->render('shops/form', title => ($is_new ? t8('Add shop') : t8('Edit shop')));
+}
+
+sub action_save {
+  my ($self) = @_;
+
+  $self->create_or_update;
+}
+
+sub action_delete {
+  my ($self) = @_;
+
+  if ( eval { $self->shop->delete; 1; } ) {
+    flash_later('info',  $::locale->text('The shop has been deleted.'));
+  } else {
+    flash_later('error', $::locale->text('The shop is in use and cannot be deleted.'));
+  };
+  $self->redirect_to(action => 'list');
+}
+
+sub action_reorder {
+  my ($self) = @_;
+
+  SL::DB::Shop->reorder_list(@{ $::form->{shop_id} || [] });
+  $self->render(\'', { type => 'json' }); # ' emacs happy again
+}
+
+sub action_check_connectivity {
+  my ($self) = @_;
+
+  my $ok = 0;
+  require SL::Shop;
+  my $shop = SL::Shop->new( config => $self->shop );
+  my $connect = $shop->check_connectivity;
+  $ok       = $connect->{success};
+  my  $version = $connect->{data}->{version};
+  $self->render('shops/test_shop_connection', { layout => 0 },
+                title   => t8('Shop Connection Test'),
+                ok      => $ok,
+                version => $version);
+}
+
+sub check_auth {
+  $::auth->assert('config');
+}
+
+sub init_shop {
+  SL::DB::Manager::Shop->find_by_or_create(id => $::form->{id} || 0)->assign_attributes(%{ $::form->{shop} });
+}
+
+#
+# helpers
+#
+
+sub create_or_update {
+  my ($self) = @_;
+
+  my $is_new = !$self->shop->id;
+
+  my @errors = $self->shop->validate;
+  if (@errors) {
+    flash('error', @errors);
+    $self->load_types();
+    $self->action_edit();
+    return;
+  }
+
+  $self->shop->save;
+
+  flash_later('info', $is_new ? t8('The shop has been created.') : t8('The shop has been saved.'));
+  $self->redirect_to(action => 'list');
+}
+
+sub load_types {
+  my ($self) = @_;
+  # data for the dropdowns when editing Shop configs
+
+  require SL::ShopConnector::ALL;
+  $self->connectors(SL::ShopConnector::ALL->connectors);
+
+  $self->price_types( [ { id => "brutto", name => t8('brutto') },
+                        { id => "netto",  name => t8('netto')  } ] );
+
+  $self->protocols(   [ { id => "http",  name => t8('http') },
+                        { id => "https", name => t8('https') } ] );
+
+  my $pricesources;
+  push(@{ $pricesources } , { id => "master_data/sellprice", name => t8("Master Data") . " - " . t8("Sellprice") },
+                            { id => "master_data/listprice", name => t8("Master Data") . " - " . t8("Listprice") },
+                            { id => "master_data/lastcost",  name => t8("Master Data") . " - " . t8("Lastcost")  });
+  my $pricegroups = SL::DB::Manager::Pricegroup->get_all;
+  foreach my $pg ( @$pricegroups ) {
+    push( @{ $pricesources } , { id => "pricegroup/" . $pg->id, name => t8("Pricegroup") . " - " . $pg->pricegroup} );
+  };
+
+  $self->price_sources($pricesources);
+
+  #Buchungsgruppen for calculate the tax for an article
+  my $taxkey_ids;
+  my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted();
+
+  foreach my $tz (@$taxzones) {
+    push  @{ $taxkey_ids }, { id => $tz->id, name => $tz->description };
+  }
+  $self->taxzone_id( $taxkey_ids );
+};
+
+sub _setup_form_action_bar {
+  my ($self) = @_;
+
+  for my $bar ($::request->layout->get('actionbar')) {
+    $bar->add(
+      combobox => [
+        action => [
+          t8('Save'),
+          submit    => [ '#form', { action => "Shop/save" } ],
+          accesskey => 'enter',
+        ],
+         action => [
+          t8('Delete'),
+          submit => [ '#form', { action => "Shop/delete" } ],
+        ],
+      ],
+      action => [
+        t8('Check Api'),
+        call => [ 'kivi.Shop.check_connectivity', id => "form" ],
+        tooltip => t8('Check connectivity'),
+      ],
+      action => [
+        t8('Cancel'),
+        submit => [ '#form', { action => "Shop/list" } ],
+      ],
+    );
+  }
+}
+
+sub _setup_list_action_bar {
+  my ($self) = @_;
+
+  for my $bar ($::request->layout->get('actionbar')) {
+    $bar->add(
+      link => [
+        t8('Add'),
+        link => $self->url_for(action => 'edit'),
+      ],
+    )
+  };
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+  SL::Controller::Shop
+
+=head1 SYNOPSIS
+
+
+=head1 DESCRIPTION
+
+
+=head1 BUGS
+
+None yet. :)
+
+=head1 AUTHOR
+
+G. Richardson E<lt>information@kivitendo-premium.deE<gt>
+W. Hahn E<lt>wh@futureworldsearch.netE<gt>
diff --git a/js/kivi.Shop.js b/js/kivi.Shop.js
new file mode 100644 (file)
index 0000000..b2c0a7d
--- /dev/null
@@ -0,0 +1,17 @@
+namespace('kivi.Shop', function(ns) {
+
+ ns.check_connectivity = function() {
+   var dat = $('form').serializeArray();
+    kivi.popup_dialog({
+      url:    'controller.pl?action=Shop/check_connectivity',
+      data:   dat,
+      type:   'POST',
+      id:     'test_shop_connection_window',
+      dialog: { title: kivi.t8('Shop Connection Test') },
+      width: 60,
+      height: 40,
+    });
+    return true;
+  };
+
+});
diff --git a/templates/webpages/shops/form.html b/templates/webpages/shops/form.html
new file mode 100644 (file)
index 0000000..b904a4d
--- /dev/null
@@ -0,0 +1,104 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE P -%][%- USE T8 -%]
+[%- USE Dumper -%]
+
+[% SET style="width: 400px" %]
+[% SET size=34 %]
+
+<h1>[% HTML.escape(title) %]</h1>
+[% #Dumper.dump_html(SELF.shop) %]
+<form id="form" action="controller.pl" method="post">
+
+[%- INCLUDE 'common/flash.html' %]
+
+[%- L.hidden_tag("id", SELF.shop.id) %]
+
+<table>
+  <tr>
+    <th align="right">[% 'Description' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.description", SELF.shop.description, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Shop type' | $T8 %]</th>
+    <td>[% L.select_tag('shop.connector', SELF.connectors, value_key = 'id', title_key = 'description', with_empty = 0, default = SELF.shop.connector, default_value_key='id' ) %]</td>
+  <tr>
+  <tr>
+    <th align="right">[% 'Price type' | $T8 %]</th>
+    <td>[% L.select_tag('shop.pricetype', SELF.price_types, value_key = 'id', title_key = 'name', with_empty = 0, default = SELF.shop.pricetype, default_value_key='id' ) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Price Source' | $T8 %]</th>
+    <td>[% L.select_tag('shop.price_source', SELF.price_sources, value_key = 'id', title_key = 'name', with_empty = 0, default = SELF.shop.price_source, default_value_key='id' ) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Bookinggroup/Tax' | $T8 %]</th>
+    <td>[% L.select_tag('shop.taxzone_id', SELF.taxzone_id, value_key = 'id', title_key = 'name', with_empty = 0, default = SELF.shop.taxzone_id, default_value_key='id' ) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Protocol' | $T8 %]</th>
+    <td>[% L.select_tag('shop.protocol', SELF.protocols value_key = 'id', title_key = 'name', with_empty = 0, default = SELF.shop.protocol, default_value_key='id' ) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Server' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.server", SELF.shop.server, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Port' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.port", SELF.shop.port, size=5) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Path' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.path", SELF.shop.path, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Realm' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.realm", SELF.shop.realm, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'User' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.login", SELF.shop.login, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Password' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.password", SELF.shop.password, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Last ordernumber' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.last_order_number", SELF.shop.last_order_number, size=12) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Orders to fetch' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.orders_to_fetch", SELF.shop.orders_to_fetch, size=12) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Transaction description' | $T8 %]</th>
+    <td>[%- L.input_tag("shop.transaction_description", SELF.shop.transaction_description, size=size) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Obsolete' | $T8 %]</th>
+    <td>[% L.checkbox_tag('shop.obsolete', checked = SELF.shop.obsolete, for_submit=1) %]</td>
+  </tr>
+</table>
+
+ <hr>
+
+<script type="text/javascript">
+<!--
+function check_prerequisites() {
+  if ($('#shop_description').val() === "") {
+    alert(kivi.t8('The name is missing.'));
+    return false;
+  }
+  if ($('#shop_url').val() === "") {
+    alert(kivi.t8('The URL is missing.'));
+    return false;
+  }
+  if ($('#shop_port').val() === "") {
+    alert(kivi.t8('The port is missing.'));
+    return false;
+  }
+
+  return true;
+}
+-->
+</script>
+</form>
diff --git a/templates/webpages/shops/list.html b/templates/webpages/shops/list.html
new file mode 100644 (file)
index 0000000..6ea62b4
--- /dev/null
@@ -0,0 +1,31 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][%- INCLUDE 'common/flash.html' %]
+
+<h1>[% title %]</h1>
+
+<p>
+ <table width="100%" id="shop_list">
+  <thead>
+   <tr class="listheading">
+    <th align="center" width="1%"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></th>
+    <th>[% 'Description' | $T8 %]</th>
+    <th>[% 'Type' | $T8 %]</th>
+    <th>[% 'Obsolete' | $T8 %]</th>
+   </tr>
+  </thead>
+
+  <tbody>
+   [%- FOREACH shop = SHOPS %]
+    <tr class="listrow" id="shop_id_[% shop.id %]">
+     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></td>
+     <td><a href="[% SELF.url_for(action='edit', id=shop.id) %]">[% HTML.escape(shop.description) %]</a></td>
+     <td>[% HTML.escape(shop.connector) %]</a></td>
+     <td>[% HTML.escape(shop.obsolete) %]</td>
+    </tr>
+   [%- END %]
+  </tbody>
+ </table>
+</p>
+
+<hr height="3">
+
+[% L.sortable_element('#shop_list tbody', url=SELF.url_for(action='reorder'), with='shop_id') %]
diff --git a/templates/webpages/shops/test_shop_connection.html b/templates/webpages/shops/test_shop_connection.html
new file mode 100644 (file)
index 0000000..d9ff482
--- /dev/null
@@ -0,0 +1,20 @@
+[%- USE HTML %][%- USE LxERP -%][%- USE L -%]
+[%- IF ok %]
+
+ <p class="message_ok">[% LxERP.t8('The connection was to the shop established successfully.') %]</p>
+ <p>[% LxERP.t8('Version: ')%][% HTML.escape(version) %]</p>
+
+[%- ELSE %]
+
+ <p class="message_error">
+  [% LxERP.t8('The connection to the shop could not be established.') %]
+  [% LxERP.t8('Error message from the webshop api:') %]
+ </p>
+
+ <p>[% HTML.escape(version) %]</p>
+
+[%- END %]
+
+<div>
+ <a href="#" onclick="$('#test_shop_connection_window').dialog('close');">[% LxERP.t8("Close Window") %]</a>
+</div>