Revision de1e3e16
Von Werner Hahn vor mehr als 7 Jahren hinzugefügt
SL/Controller/Shop.pm | ||
---|---|---|
1 |
package SL::Controller::Shop; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(SL::Controller::Base); |
|
6 |
|
|
7 |
use SL::Helper::Flash; |
|
8 |
use SL::Locale::String; |
|
9 |
use SL::DB::Default; |
|
10 |
use SL::DB::Manager::Shop; |
|
11 |
use SL::DB::Pricegroup; |
|
12 |
use SL::DB::TaxZone; |
|
13 |
|
|
14 |
use Rose::Object::MakeMethods::Generic ( |
|
15 |
scalar => [ qw(connectors price_types price_sources taxzone_id protocols) ], |
|
16 |
'scalar --get_set_init' => [ qw(shop) ] |
|
17 |
); |
|
18 |
|
|
19 |
__PACKAGE__->run_before('check_auth'); |
|
20 |
__PACKAGE__->run_before('load_types', only => [ qw(new edit) ]); |
|
21 |
|
|
22 |
# |
|
23 |
# actions |
|
24 |
# |
|
25 |
|
|
26 |
sub action_list { |
|
27 |
my ($self) = @_; |
|
28 |
|
|
29 |
$self->_setup_list_action_bar; |
|
30 |
$self->render('shops/list', |
|
31 |
title => t8('Shops'), |
|
32 |
SHOPS => SL::DB::Manager::Shop->get_all_sorted, |
|
33 |
); |
|
34 |
} |
|
35 |
|
|
36 |
sub action_edit { |
|
37 |
my ($self) = @_; |
|
38 |
|
|
39 |
my $is_new = !$self->shop->id; |
|
40 |
$self->_setup_form_action_bar; |
|
41 |
$self->render('shops/form', title => ($is_new ? t8('Add shop') : t8('Edit shop'))); |
|
42 |
} |
|
43 |
|
|
44 |
sub action_save { |
|
45 |
my ($self) = @_; |
|
46 |
|
|
47 |
$self->create_or_update; |
|
48 |
} |
|
49 |
|
|
50 |
sub action_delete { |
|
51 |
my ($self) = @_; |
|
52 |
|
|
53 |
if ( eval { $self->shop->delete; 1; } ) { |
|
54 |
flash_later('info', $::locale->text('The shop has been deleted.')); |
|
55 |
} else { |
|
56 |
flash_later('error', $::locale->text('The shop is in use and cannot be deleted.')); |
|
57 |
}; |
|
58 |
$self->redirect_to(action => 'list'); |
|
59 |
} |
|
60 |
|
|
61 |
sub action_reorder { |
|
62 |
my ($self) = @_; |
|
63 |
|
|
64 |
SL::DB::Shop->reorder_list(@{ $::form->{shop_id} || [] }); |
|
65 |
$self->render(\'', { type => 'json' }); # ' emacs happy again |
|
66 |
} |
|
67 |
|
|
68 |
sub action_check_connectivity { |
|
69 |
my ($self) = @_; |
|
70 |
|
|
71 |
my $ok = 0; |
|
72 |
require SL::Shop; |
|
73 |
my $shop = SL::Shop->new( config => $self->shop ); |
|
74 |
my $connect = $shop->check_connectivity; |
|
75 |
$ok = $connect->{success}; |
|
76 |
my $version = $connect->{data}->{version}; |
|
77 |
$self->render('shops/test_shop_connection', { layout => 0 }, |
|
78 |
title => t8('Shop Connection Test'), |
|
79 |
ok => $ok, |
|
80 |
version => $version); |
|
81 |
} |
|
82 |
|
|
83 |
sub check_auth { |
|
84 |
$::auth->assert('config'); |
|
85 |
} |
|
86 |
|
|
87 |
sub init_shop { |
|
88 |
SL::DB::Manager::Shop->find_by_or_create(id => $::form->{id} || 0)->assign_attributes(%{ $::form->{shop} }); |
|
89 |
} |
|
90 |
|
|
91 |
# |
|
92 |
# helpers |
|
93 |
# |
|
94 |
|
|
95 |
sub create_or_update { |
|
96 |
my ($self) = @_; |
|
97 |
|
|
98 |
my $is_new = !$self->shop->id; |
|
99 |
|
|
100 |
my @errors = $self->shop->validate; |
|
101 |
if (@errors) { |
|
102 |
flash('error', @errors); |
|
103 |
$self->load_types(); |
|
104 |
$self->action_edit(); |
|
105 |
return; |
|
106 |
} |
|
107 |
|
|
108 |
$self->shop->save; |
|
109 |
|
|
110 |
flash_later('info', $is_new ? t8('The shop has been created.') : t8('The shop has been saved.')); |
|
111 |
$self->redirect_to(action => 'list'); |
|
112 |
} |
|
113 |
|
|
114 |
sub load_types { |
|
115 |
my ($self) = @_; |
|
116 |
# data for the dropdowns when editing Shop configs |
|
117 |
|
|
118 |
require SL::ShopConnector::ALL; |
|
119 |
$self->connectors(SL::ShopConnector::ALL->connectors); |
|
120 |
|
|
121 |
$self->price_types( [ { id => "brutto", name => t8('brutto') }, |
|
122 |
{ id => "netto", name => t8('netto') } ] ); |
|
123 |
|
|
124 |
$self->protocols( [ { id => "http", name => t8('http') }, |
|
125 |
{ id => "https", name => t8('https') } ] ); |
|
126 |
|
|
127 |
my $pricesources; |
|
128 |
push(@{ $pricesources } , { id => "master_data/sellprice", name => t8("Master Data") . " - " . t8("Sellprice") }, |
|
129 |
{ id => "master_data/listprice", name => t8("Master Data") . " - " . t8("Listprice") }, |
|
130 |
{ id => "master_data/lastcost", name => t8("Master Data") . " - " . t8("Lastcost") }); |
|
131 |
my $pricegroups = SL::DB::Manager::Pricegroup->get_all; |
|
132 |
foreach my $pg ( @$pricegroups ) { |
|
133 |
push( @{ $pricesources } , { id => "pricegroup/" . $pg->id, name => t8("Pricegroup") . " - " . $pg->pricegroup} ); |
|
134 |
}; |
|
135 |
|
|
136 |
$self->price_sources($pricesources); |
|
137 |
|
|
138 |
#Buchungsgruppen for calculate the tax for an article |
|
139 |
my $taxkey_ids; |
|
140 |
my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted(); |
|
141 |
|
|
142 |
foreach my $tz (@$taxzones) { |
|
143 |
push @{ $taxkey_ids }, { id => $tz->id, name => $tz->description }; |
|
144 |
} |
|
145 |
$self->taxzone_id( $taxkey_ids ); |
|
146 |
}; |
|
147 |
|
|
148 |
sub _setup_form_action_bar { |
|
149 |
my ($self) = @_; |
|
150 |
|
|
151 |
for my $bar ($::request->layout->get('actionbar')) { |
|
152 |
$bar->add( |
|
153 |
combobox => [ |
|
154 |
action => [ |
|
155 |
t8('Save'), |
|
156 |
submit => [ '#form', { action => "Shop/save" } ], |
|
157 |
accesskey => 'enter', |
|
158 |
], |
|
159 |
action => [ |
|
160 |
t8('Delete'), |
|
161 |
submit => [ '#form', { action => "Shop/delete" } ], |
|
162 |
], |
|
163 |
], |
|
164 |
action => [ |
|
165 |
t8('Check Api'), |
|
166 |
call => [ 'kivi.Shop.check_connectivity', id => "form" ], |
|
167 |
tooltip => t8('Check connectivity'), |
|
168 |
], |
|
169 |
action => [ |
|
170 |
t8('Cancel'), |
|
171 |
submit => [ '#form', { action => "Shop/list" } ], |
|
172 |
], |
|
173 |
); |
|
174 |
} |
|
175 |
} |
|
176 |
|
|
177 |
sub _setup_list_action_bar { |
|
178 |
my ($self) = @_; |
|
179 |
|
|
180 |
for my $bar ($::request->layout->get('actionbar')) { |
|
181 |
$bar->add( |
|
182 |
link => [ |
|
183 |
t8('Add'), |
|
184 |
link => $self->url_for(action => 'edit'), |
|
185 |
], |
|
186 |
) |
|
187 |
}; |
|
188 |
} |
|
189 |
|
|
190 |
1; |
|
191 |
|
|
192 |
__END__ |
|
193 |
|
|
194 |
=encoding utf-8 |
|
195 |
|
|
196 |
=head1 NAME |
|
197 |
|
|
198 |
SL::Controller::Shop |
|
199 |
|
|
200 |
=head1 SYNOPSIS |
|
201 |
|
|
202 |
|
|
203 |
=head1 DESCRIPTION |
|
204 |
|
|
205 |
|
|
206 |
=head1 BUGS |
|
207 |
|
|
208 |
None yet. :) |
|
209 |
|
|
210 |
=head1 AUTHOR |
|
211 |
|
|
212 |
G. Richardson E<lt>information@kivitendo-premium.deE<gt> |
|
213 |
W. Hahn E<lt>wh@futureworldsearch.netE<gt> |
js/kivi.Shop.js | ||
---|---|---|
1 |
namespace('kivi.Shop', function(ns) { |
|
2 |
|
|
3 |
ns.check_connectivity = function() { |
|
4 |
var dat = $('form').serializeArray(); |
|
5 |
kivi.popup_dialog({ |
|
6 |
url: 'controller.pl?action=Shop/check_connectivity', |
|
7 |
data: dat, |
|
8 |
type: 'POST', |
|
9 |
id: 'test_shop_connection_window', |
|
10 |
dialog: { title: kivi.t8('Shop Connection Test') }, |
|
11 |
width: 60, |
|
12 |
height: 40, |
|
13 |
}); |
|
14 |
return true; |
|
15 |
}; |
|
16 |
|
|
17 |
}); |
templates/webpages/shops/form.html | ||
---|---|---|
1 |
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE P -%][%- USE T8 -%] |
|
2 |
[%- USE Dumper -%] |
|
3 |
|
|
4 |
[% SET style="width: 400px" %] |
|
5 |
[% SET size=34 %] |
|
6 |
|
|
7 |
<h1>[% HTML.escape(title) %]</h1> |
|
8 |
[% #Dumper.dump_html(SELF.shop) %] |
|
9 |
<form id="form" action="controller.pl" method="post"> |
|
10 |
|
|
11 |
[%- INCLUDE 'common/flash.html' %] |
|
12 |
|
|
13 |
[%- L.hidden_tag("id", SELF.shop.id) %] |
|
14 |
|
|
15 |
<table> |
|
16 |
<tr> |
|
17 |
<th align="right">[% 'Description' | $T8 %]</th> |
|
18 |
<td>[%- L.input_tag("shop.description", SELF.shop.description, size=size) %]</td> |
|
19 |
</tr> |
|
20 |
<tr> |
|
21 |
<th align="right">[% 'Shop type' | $T8 %]</th> |
|
22 |
<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> |
|
23 |
<tr> |
|
24 |
<tr> |
|
25 |
<th align="right">[% 'Price type' | $T8 %]</th> |
|
26 |
<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> |
|
27 |
</tr> |
|
28 |
<tr> |
|
29 |
<th align="right">[% 'Price Source' | $T8 %]</th> |
|
30 |
<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> |
|
31 |
</tr> |
|
32 |
<tr> |
|
33 |
<th align="right">[% 'Bookinggroup/Tax' | $T8 %]</th> |
|
34 |
<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> |
|
35 |
</tr> |
|
36 |
<tr> |
|
37 |
<th align="right">[% 'Protocol' | $T8 %]</th> |
|
38 |
<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> |
|
39 |
</tr> |
|
40 |
<tr> |
|
41 |
<th align="right">[% 'Server' | $T8 %]</th> |
|
42 |
<td>[%- L.input_tag("shop.server", SELF.shop.server, size=size) %]</td> |
|
43 |
</tr> |
|
44 |
<tr> |
|
45 |
<th align="right">[% 'Port' | $T8 %]</th> |
|
46 |
<td>[%- L.input_tag("shop.port", SELF.shop.port, size=5) %]</td> |
|
47 |
</tr> |
|
48 |
<tr> |
|
49 |
<th align="right">[% 'Path' | $T8 %]</th> |
|
50 |
<td>[%- L.input_tag("shop.path", SELF.shop.path, size=size) %]</td> |
|
51 |
</tr> |
|
52 |
<tr> |
|
53 |
<th align="right">[% 'Realm' | $T8 %]</th> |
|
54 |
<td>[%- L.input_tag("shop.realm", SELF.shop.realm, size=size) %]</td> |
|
55 |
</tr> |
|
56 |
<tr> |
|
57 |
<th align="right">[% 'User' | $T8 %]</th> |
|
58 |
<td>[%- L.input_tag("shop.login", SELF.shop.login, size=size) %]</td> |
|
59 |
</tr> |
|
60 |
<tr> |
|
61 |
<th align="right">[% 'Password' | $T8 %]</th> |
|
62 |
<td>[%- L.input_tag("shop.password", SELF.shop.password, size=size) %]</td> |
|
63 |
</tr> |
|
64 |
<tr> |
|
65 |
<th align="right">[% 'Last ordernumber' | $T8 %]</th> |
|
66 |
<td>[%- L.input_tag("shop.last_order_number", SELF.shop.last_order_number, size=12) %]</td> |
|
67 |
</tr> |
|
68 |
<tr> |
|
69 |
<th align="right">[% 'Orders to fetch' | $T8 %]</th> |
|
70 |
<td>[%- L.input_tag("shop.orders_to_fetch", SELF.shop.orders_to_fetch, size=12) %]</td> |
|
71 |
</tr> |
|
72 |
<tr> |
|
73 |
<th align="right">[% 'Transaction description' | $T8 %]</th> |
|
74 |
<td>[%- L.input_tag("shop.transaction_description", SELF.shop.transaction_description, size=size) %]</td> |
|
75 |
</tr> |
|
76 |
<tr> |
|
77 |
<th align="right">[% 'Obsolete' | $T8 %]</th> |
|
78 |
<td>[% L.checkbox_tag('shop.obsolete', checked = SELF.shop.obsolete, for_submit=1) %]</td> |
|
79 |
</tr> |
|
80 |
</table> |
|
81 |
|
|
82 |
<hr> |
|
83 |
|
|
84 |
<script type="text/javascript"> |
|
85 |
<!-- |
|
86 |
function check_prerequisites() { |
|
87 |
if ($('#shop_description').val() === "") { |
|
88 |
alert(kivi.t8('The name is missing.')); |
|
89 |
return false; |
|
90 |
} |
|
91 |
if ($('#shop_url').val() === "") { |
|
92 |
alert(kivi.t8('The URL is missing.')); |
|
93 |
return false; |
|
94 |
} |
|
95 |
if ($('#shop_port').val() === "") { |
|
96 |
alert(kivi.t8('The port is missing.')); |
|
97 |
return false; |
|
98 |
} |
|
99 |
|
|
100 |
return true; |
|
101 |
} |
|
102 |
--> |
|
103 |
</script> |
|
104 |
</form> |
templates/webpages/shops/list.html | ||
---|---|---|
1 |
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][%- INCLUDE 'common/flash.html' %] |
|
2 |
|
|
3 |
<h1>[% title %]</h1> |
|
4 |
|
|
5 |
<p> |
|
6 |
<table width="100%" id="shop_list"> |
|
7 |
<thead> |
|
8 |
<tr class="listheading"> |
|
9 |
<th align="center" width="1%"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></th> |
|
10 |
<th>[% 'Description' | $T8 %]</th> |
|
11 |
<th>[% 'Type' | $T8 %]</th> |
|
12 |
<th>[% 'Obsolete' | $T8 %]</th> |
|
13 |
</tr> |
|
14 |
</thead> |
|
15 |
|
|
16 |
<tbody> |
|
17 |
[%- FOREACH shop = SHOPS %] |
|
18 |
<tr class="listrow" id="shop_id_[% shop.id %]"> |
|
19 |
<td align="center" class="dragdrop"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></td> |
|
20 |
<td><a href="[% SELF.url_for(action='edit', id=shop.id) %]">[% HTML.escape(shop.description) %]</a></td> |
|
21 |
<td>[% HTML.escape(shop.connector) %]</a></td> |
|
22 |
<td>[% HTML.escape(shop.obsolete) %]</td> |
|
23 |
</tr> |
|
24 |
[%- END %] |
|
25 |
</tbody> |
|
26 |
</table> |
|
27 |
</p> |
|
28 |
|
|
29 |
<hr height="3"> |
|
30 |
|
|
31 |
[% L.sortable_element('#shop_list tbody', url=SELF.url_for(action='reorder'), with='shop_id') %] |
templates/webpages/shops/test_shop_connection.html | ||
---|---|---|
1 |
[%- USE HTML %][%- USE LxERP -%][%- USE L -%] |
|
2 |
[%- IF ok %] |
|
3 |
|
|
4 |
<p class="message_ok">[% LxERP.t8('The connection was to the shop established successfully.') %]</p> |
|
5 |
<p>[% LxERP.t8('Version: ')%][% HTML.escape(version) %]</p> |
|
6 |
|
|
7 |
[%- ELSE %] |
|
8 |
|
|
9 |
<p class="message_error"> |
|
10 |
[% LxERP.t8('The connection to the shop could not be established.') %] |
|
11 |
[% LxERP.t8('Error message from the webshop api:') %] |
|
12 |
</p> |
|
13 |
|
|
14 |
<p>[% HTML.escape(version) %]</p> |
|
15 |
|
|
16 |
[%- END %] |
|
17 |
|
|
18 |
<div> |
|
19 |
<a href="#" onclick="$('#test_shop_connection_window').dialog('close');">[% LxERP.t8("Close Window") %]</a> |
|
20 |
</div> |
Auch abrufbar als: Unified diff
WebshopApi: Shop Controller