From de1e3e16945e61aac5eacfb254356d968add876d Mon Sep 17 00:00:00 2001 From: Werner Hahn Date: Fri, 22 Sep 2017 02:25:37 +0200 Subject: [PATCH] WebshopApi: Shop Controller --- SL/Controller/Shop.pm | 213 ++++++++++++++++++ js/kivi.Shop.js | 17 ++ templates/webpages/shops/form.html | 104 +++++++++ templates/webpages/shops/list.html | 31 +++ .../webpages/shops/test_shop_connection.html | 20 ++ 5 files changed, 385 insertions(+) create mode 100644 SL/Controller/Shop.pm create mode 100644 js/kivi.Shop.js create mode 100644 templates/webpages/shops/form.html create mode 100644 templates/webpages/shops/list.html create mode 100644 templates/webpages/shops/test_shop_connection.html diff --git a/SL/Controller/Shop.pm b/SL/Controller/Shop.pm new file mode 100644 index 000000000..afc766296 --- /dev/null +++ b/SL/Controller/Shop.pm @@ -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 Einformation@kivitendo-premium.deE +W. Hahn Ewh@futureworldsearch.netE diff --git a/js/kivi.Shop.js b/js/kivi.Shop.js new file mode 100644 index 000000000..b2c0a7d34 --- /dev/null +++ b/js/kivi.Shop.js @@ -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 index 000000000..b904a4d83 --- /dev/null +++ b/templates/webpages/shops/form.html @@ -0,0 +1,104 @@ +[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE P -%][%- USE T8 -%] +[%- USE Dumper -%] + +[% SET style="width: 400px" %] +[% SET size=34 %] + +

[% HTML.escape(title) %]

+[% #Dumper.dump_html(SELF.shop) %] +
+ +[%- INCLUDE 'common/flash.html' %] + +[%- L.hidden_tag("id", SELF.shop.id) %] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[% 'Description' | $T8 %][%- L.input_tag("shop.description", SELF.shop.description, size=size) %]
[% 'Shop type' | $T8 %][% L.select_tag('shop.connector', SELF.connectors, value_key = 'id', title_key = 'description', with_empty = 0, default = SELF.shop.connector, default_value_key='id' ) %]
[% 'Price type' | $T8 %][% 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' ) %]
[% 'Price Source' | $T8 %][% 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' ) %]
[% 'Bookinggroup/Tax' | $T8 %][% 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' ) %]
[% 'Protocol' | $T8 %][% L.select_tag('shop.protocol', SELF.protocols value_key = 'id', title_key = 'name', with_empty = 0, default = SELF.shop.protocol, default_value_key='id' ) %]
[% 'Server' | $T8 %][%- L.input_tag("shop.server", SELF.shop.server, size=size) %]
[% 'Port' | $T8 %][%- L.input_tag("shop.port", SELF.shop.port, size=5) %]
[% 'Path' | $T8 %][%- L.input_tag("shop.path", SELF.shop.path, size=size) %]
[% 'Realm' | $T8 %][%- L.input_tag("shop.realm", SELF.shop.realm, size=size) %]
[% 'User' | $T8 %][%- L.input_tag("shop.login", SELF.shop.login, size=size) %]
[% 'Password' | $T8 %][%- L.input_tag("shop.password", SELF.shop.password, size=size) %]
[% 'Last ordernumber' | $T8 %][%- L.input_tag("shop.last_order_number", SELF.shop.last_order_number, size=12) %]
[% 'Orders to fetch' | $T8 %][%- L.input_tag("shop.orders_to_fetch", SELF.shop.orders_to_fetch, size=12) %]
[% 'Transaction description' | $T8 %][%- L.input_tag("shop.transaction_description", SELF.shop.transaction_description, size=size) %]
[% 'Obsolete' | $T8 %][% L.checkbox_tag('shop.obsolete', checked = SELF.shop.obsolete, for_submit=1) %]
+ +
+ + +
diff --git a/templates/webpages/shops/list.html b/templates/webpages/shops/list.html new file mode 100644 index 000000000..6ea62b411 --- /dev/null +++ b/templates/webpages/shops/list.html @@ -0,0 +1,31 @@ +[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][%- INCLUDE 'common/flash.html' %] + +

[% title %]

+ +

+ + + + + + + + + + + + [%- FOREACH shop = SHOPS %] + + + + + + + [%- END %] + +
[ LxERP.t8('reorder item') %][% 'Description' | $T8 %][% 'Type' | $T8 %][% 'Obsolete' | $T8 %]
[ LxERP.t8('reorder item') %][% HTML.escape(shop.description) %][% HTML.escape(shop.connector) %][% HTML.escape(shop.obsolete) %]
+

+ +
+ +[% 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 index 000000000..d9ff48254 --- /dev/null +++ b/templates/webpages/shops/test_shop_connection.html @@ -0,0 +1,20 @@ +[%- USE HTML %][%- USE LxERP -%][%- USE L -%] +[%- IF ok %] + +

[% LxERP.t8('The connection was to the shop established successfully.') %]

+

[% LxERP.t8('Version: ')%][% HTML.escape(version) %]

+ +[%- ELSE %] + +

+ [% LxERP.t8('The connection to the shop could not be established.') %] + [% LxERP.t8('Error message from the webshop api:') %] +

+ +

[% HTML.escape(version) %]

+ +[%- END %] + + -- 2.20.1