Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 9ea9a998

Von Kivitendo Admin vor mehr als 8 Jahren hinzugefügt

  • ID 9ea9a9989038b52db3b881d4eb00729ee296d1c7
  • Vorgänger 72903759
  • Nachfolger fa1a87de

Shop - SL/Shop and Shop Controller for editing shop configs

Unterschiede anzeigen:

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

  
13
use Rose::Object::MakeMethods::Generic (
14
  scalar                  => [ qw(connectors price_types price_sources) ],
15
  'scalar --get_set_init' => [ qw(shop) ]
16
);
17

  
18
__PACKAGE__->run_before('check_auth');
19
__PACKAGE__->run_before('load_types',    only => [ qw(new edit) ]);
20

  
21
#
22
# actions
23
#
24

  
25
sub action_list {
26
  my ($self) = @_;
27

  
28
  $self->render('shops/list',
29
                title => t8('Shops'),
30
                SHOPS => SL::DB::Manager::Shop->get_all_sorted,
31
               );
32
}
33

  
34
sub action_new {
35
  my ($self) = @_;
36

  
37
  $self->shop(SL::DB::Shop->new);
38
  $self->render('shops/form', title       => t8('Add shop'));
39
};
40

  
41
sub action_edit {
42
  my ($self) = @_;
43

  
44
  $self->render('shops/form', title       => t8('Edit shop'));
45
}
46

  
47
sub action_create {
48
  my ($self) = @_;
49

  
50
  $self->shop(SL::DB::Shop->new);
51
  $self->create_or_update;
52
}
53

  
54
sub action_update {
55
  my ($self) = @_;
56
  $self->create_or_update;
57
}
58

  
59
sub action_delete {
60
  my ($self) = @_;
61

  
62
  if ( eval { $self->shop->delete; 1; } ) {
63
    flash_later('info',  $::locale->text('The shop has been deleted.'));
64
  } else {
65
    flash_later('error', $::locale->text('The shop has been used and cannot be deleted.'));
66
  };
67
  $self->redirect_to(action => 'list');
68
}
69

  
70
sub action_reorder {
71
  my ($self) = @_;
72

  
73
  SL::DB::Shop->reorder_list(@{ $::form->{shop_id} || [] });
74
  $self->render(\'', { type => 'json' });
75
}
76

  
77
#
78
# filters
79
#
80

  
81
sub check_auth {
82
  $::auth->assert('config');
83
}
84

  
85
sub init_shop {
86
  SL::DB::Shop->new(id => $::form->{id})->load;
87
}
88

  
89
#
90
# helpers
91
#
92

  
93
sub create_or_update {
94
  my ($self) = @_;
95
  my $is_new = !$self->shop->id;
96

  
97
  my $params = delete($::form->{shop}) || { };
98

  
99
  $self->shop->assign_attributes(%{ $params });
100

  
101
  my @errors = $self->shop->validate;
102

  
103
  if (@errors) {
104
    flash('error', @errors);
105
    $self->render('shops/form',
106
                   title => $is_new ? t8('Add shop') : t8('Edit shop'));
107
    return;
108
  }
109

  
110
  $self->shop->save;
111

  
112
  flash_later('info', $is_new ? t8('The shop has been created.') : t8('The shop has been saved.'));
113
  $self->redirect_to(action => 'list');
114
}
115

  
116
sub load_types {
117
  my ($self) = @_;
118
  # data for the dropdowns when editing Shop configs
119

  
120
  # hardcoded the possible connectors, which correspond to
121
  # SL/ShopConnector/xxxx classes
122
  $self->connectors( [ { id => "xtcommerce", description => "XT Commerce"},
123
                       { id => "shopware",   description => "Shopware" },
124
                       { id => "ideal",      description => "IDeal" }
125
                     ]);
126

  
127
  # whether the shop presents its prices as brutto or netto
128
  $self->price_types( [ { id => "brutto", name => t8('brutto')}, { id => "netto", name => t8('netto') } ] );
129

  
130
  # the possible price sources to use for the shops: sellprice, lastcost,
131
  # listprice, or one of the pricegroups
132
  my $pricesources;
133
  push( @{ $pricesources } , { id => "sellprice", name => t8("Sellprice") },
134
                             { id => "listprice", name => t8("Listprice") },
135
                             { id => "lastcost",  name => t8("Lastcost") }
136
                             );
137
  my $pricegroups = SL::DB::Manager::Pricegroup->get_all;
138
  foreach my $pg ( @$pricegroups ) {
139
    push( @{ $pricesources } , { id => $pg->id, name => $pg->pricegroup} );
140
  };
141

  
142
  $self->price_sources( $pricesources );
143
};
144

  
145

  
146
1;
SL/DB/Helper/ALL.pm
109 109
use SL::DB::SepaExportItem;
110 110
use SL::DB::SepaExportMessageId;
111 111
use SL::DB::Shipto;
112
use SL::DB::Shop;
112 113
use SL::DB::ShopPart;
113 114
use SL::DB::Status;
114 115
use SL::DB::Tax;
SL/DB/Helper/Mappings.pm
189 189
  sepa_export_message_ids        => 'SepaExportMessageId',
190 190
  schema_info                    => 'schema_info',
191 191
  shipto                         => 'shipto',
192
  shops                          => 'shop',
192 193
  shop_parts                     => 'shop_part',
193 194
  status                         => 'status',
194 195
  tax                            => 'tax',
......
202 203
  units                          => 'unit',
203 204
  units_language                 => 'units_language',
204 205
  vendor                         => 'vendor',
206
  web_shops                      => 'web_shop',
205 207
  warehouse                      => 'warehouse',
206 208
);
207 209

  
SL/DB/Manager/Shop.pm
1
# This file has been auto-generated only because it didn't exist.
2
# Feel free to modify it at will; it will not be overwritten automatically.
3

  
4
package SL::DB::Manager::Shop;
5

  
6
use strict;
7

  
8
use SL::DB::Helper::Manager;
9
use base qw(SL::DB::Helper::Manager);
10

  
11
sub object_class { 'SL::DB::Shop' }
12

  
13
use SL::DB::Helper::Sorted;
14

  
15
__PACKAGE__->make_manager_methods;
16

  
17
sub _sort_spec {
18
  return ( default => [ 'sortkey', 1 ],
19
           columns => { SIMPLE => 'ALL' } );
20
}
21

  
22
sub get_default {
23
    return $_[0]->get_first(where => [ obsolete => 0 ], sort_by => 'sortkey');
24
}
25

  
26
1;
27

  
28
1;
SL/DB/MetaSetup/Shop.pm
1
# This file has been auto-generated. Do not modify it; it will be overwritten
2
# by rose_auto_create_model.pl automatically.
3
package SL::DB::Shop;
4

  
5
use strict;
6

  
7
use base qw(SL::DB::Object);
8

  
9
__PACKAGE__->meta->table('shops');
10

  
11
__PACKAGE__->meta->columns(
12
  connector    => { type => 'text' },
13
  description  => { type => 'text' },
14
  id           => { type => 'serial', not_null => 1 },
15
  login        => { type => 'text' },
16
  obsolete     => { type => 'boolean', default => 'false', not_null => 1 },
17
  password     => { type => 'text' },
18
  port         => { type => 'integer' },
19
  price_source => { type => 'text' },
20
  pricetype    => { type => 'text' },
21
  sortkey      => { type => 'integer' },
22
  url          => { type => 'text' },
23
);
24

  
25
__PACKAGE__->meta->primary_key_columns([ 'id' ]);
26

  
27
1;
28
;
SL/DB/Part.pm
27 27
    type         => 'one to many',
28 28
    class        => 'SL::DB::Price',
29 29
    column_map   => { id => 'parts_id' },
30
    manager_args => { with_objects => [ 'pricegroup' ] }
30 31
  },
31 32
  makemodels     => {
32 33
    type         => 'one to many',
SL/DB/Shop.pm
1
# This file has been auto-generated only because it didn't exist.
2
# Feel free to modify it at will; it will not be overwritten automatically.
3

  
4
package SL::DB::Shop;
5

  
6
use strict;
7

  
8
use SL::DB::MetaSetup::Shop;
9
use SL::DB::Manager::Shop;
10
use SL::DB::Helper::ActsAsList;
11

  
12
__PACKAGE__->meta->initialize;
13

  
14
sub validate {
15
  my ($self) = @_;
16

  
17
  my @errors;
18

  
19
  push @errors, $::locale->text('The description is missing.') unless $self->{description};
20

  
21
  return @errors;
22
}
23
1;
SL/Shop.pm
1
package SL::Shop;
2

  
3
use strict;
4

  
5
use parent qw(Rose::Object);
6

  
7
# __PACKAGE__->run_before('check_auth');
8

  
9
use Rose::Object::MakeMethods::Generic (
10
  'scalar'                => [ qw(config) ],
11
  'scalar --get_set_init' => [ qw(connector) ],
12
);
13

  
14
sub init_connector {
15
  my ($self) = @_;
16
  # determine the connector from the connector type in the webshop config
17
  return SL::ShopConnector::ALL->shop_connector_class_by_name($self->config->connector)->new( config => $self->config); 
18

  
19
};
20

  
21
1;
22

  
23
__END__
24

  
25
=encoding utf8
26

  
27
=head1 NAME
28

  
29
SL::WebShop - Do stuff with WebShop instances
30

  
31
=head1 SYNOPSIS
32

  
33
  my $config = SL::DB::Manager::WebShop->get_first();
34
  my $shop = SL::WebShop->new( config => $config );
35

  
36
From the config we know which Connector class to load, save in $shop->connector
37
and do stuff from there:
38

  
39
  $shop->connector->get_new_orders;
40

  
41
=head1 FUNCTIONS
42

  
43
=head1 BUGS
44

  
45
Nothing here yet.
46

  
47
=head1 AUTHOR
48

  
49
G. Richardson <lt>information@kivitendo-premium.deE<gt>
50

  
51
=cut
52

  
menus/user/00-erp.yaml
1194 1194
  module: am.pl
1195 1195
  params:
1196 1196
    action: list_warehouses
1197
- parent: system
1198
  id: system_shops
1199
  name: Web shops
1200
  order: 2350
1201
  params:
1202
    action: Shop/list
1197 1203
- parent: system
1198 1204
  id: system_import_csv
1199 1205
  name: Import CSV
sql/Pg-upgrade2/shops.sql
1
-- @tag: shops
2
-- @description: Tabelle für Shops
3
-- @depends: release_3_3_0
4
-- @ignore: 0
5

  
6
CREATE TABLE shops (
7
  id SERIAL PRIMARY KEY,
8
  description text,
9
  obsolete BOOLEAN NOT NULL DEFAULT false,
10
  sortkey INTEGER,
11
  connector text,     -- hardcoded options, e.g. xtcommerce, shopware
12
  pricetype text,     -- netto/brutto
13
  price_source text,  -- sellprice/listprice/lastcost or pricegroup id
14
  url text,
15
  port INTEGER,
16
  login text,  -- "user" is reserved
17
  password text
18
);
templates/webpages/shops/form.html
1
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%]
2

  
3
[% SET style="width: 400px" %]
4
[% SET size=34 %]
5

  
6
<h1>[% HTML.escape(title) %]</h1>
7

  
8
<form action="controller.pl" method="post">
9

  
10
[%- INCLUDE 'common/flash.html' %]
11

  
12
[%- L.hidden_tag("id", SELF.shop.id) %]
13

  
14
<table>
15
  <tr>
16
    <th align="right">[% 'Description' | $T8 %]</th>
17
    <td>[%- L.input_tag("shop.description", SELF.shop.description, size=size) %]</td>
18
  </tr>
19
  <tr>
20
    <th align="right">[% 'Shop type' | $T8 %]</th>
21
    <td>[% L.select_tag('shop.connector', SELF.connectors, value_key = 'id', title_key = 'description', with_empty = 1, default = SELF.shop.connector, default_value_key='id' ) %]</td>
22
  <tr>
23
  <tr>
24
    <th align="right">[% 'Price type' | $T8 %]</th>
25
    <td>[% L.select_tag('shop.pricetype', SELF.price_types, value_key = 'id', title_key = 'name', with_empty = 1, default = SELF.shop.pricetype, default_value_key='id' ) %]</td>
26
  </tr>
27
  <tr>
28
    <th align="right">[% 'Price Source' | $T8 %]</th>
29
    <td>[% L.select_tag('shop.price_source', SELF.price_sources, value_key = 'id', title_key = 'name', with_empty = 1, default = SELF.shop.price_source, default_value_key='id' ) %]</td>
30
  </tr>
31
  <tr>
32
    <th align="right">[% 'URL' | $T8 %]</th>
33
    <td>[%- L.input_tag("shop.url", SELF.shop.url, size=size) %]</td>
34
  </tr>
35
  <tr>
36
    <th align="right">[% 'Port' | $T8 %]</th>
37
    <td>[%- L.input_tag("shop.port", SELF.shop.port, size=5) %]</td>
38
   <tr>
39
    <th align="right">[% 'User' | $T8 %]</th>
40
    <td>[%- L.input_tag("shop.login", SELF.shop.login, size=12) %]</td>
41
  </tr>
42
    <tr>
43
    <th align="right">[% 'Password' | $T8 %]</th>
44
    <td>[%- L.input_tag("shop.password", SELF.shop.password, size=12) %]</td>
45
  </tr>
46
 </tr>
47
  <tr>
48
    <th align="right">[% 'Obsolete' | $T8 %]</th>
49
    <td>[% L.checkbox_tag('shop.obsolete', checked = SELF.shop.obsolete, for_submit=1) %]</td>
50
  </tr>
51
</table>
52

  
53
 <p>
54
  [% L.hidden_tag("action", "Shop/dispatch") %]
55
  [% L.submit_tag("action_" _  (SELF.shop.id ? "update" : "create"), LxERP.t8('Save'), onclick="return check_prerequisites();") %]
56
  [%- IF SELF.shop.id -%]
57
    [% L.submit_tag("action_delete", LxERP.t8('Delete')) %]
58
  [%- END %]
59
  <a href="[% SELF.url_for(action='list') %]">[%- LxERP.t8("Cancel") %]</a>
60
 </p>
61

  
62
 <hr>
63

  
64
<script type="text/javascript">
65
<!--
66
function check_prerequisites() {
67
  if ($('#shop_description').val() === "") {
68
    alert(kivi.t8('The name is missing.'));
69
    return false;
70
  }
71
  if ($('#shop_url').val() === "") {
72
    alert(kivi.t8('The URL is missing.'));
73
    return false;
74
  }
75
  if ($('#shop_port').val() === "") {
76
    alert(kivi.t8('The port is missing.'));
77
    return false;
78
  }
79

  
80
  return true;
81
}
82
-->
83
</script>
84
</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
   </tr>
13
  </thead>
14

  
15
  <tbody>
16
   [%- FOREACH shop = SHOPS %]
17
    <tr class="listrow" id="shop_id_[% shop.id %]">
18
     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></td>
19
     <td><a href="[% SELF.url_for(action='edit', id=shop.id) %]">[% HTML.escape(shop.description) %]</a></td>
20
     <td>[% HTML.escape(shop.connector) %]</a></td>
21
    </tr>
22
   [%- END %]
23
  </tbody>
24
 </table>
25
</p>
26

  
27
<hr height="3">
28

  
29
[% L.sortable_element('#shop_list tbody', url=SELF.url_for(action='reorder'), with='shop_id') %]
30

  
31
<p>
32
 <a href="[% SELF.url_for(action='new') %]">[%- 'Add' | $T8 %]</a>
33
</p>

Auch abrufbar als: Unified diff