]> wagnertech.de Git - mfinanz.git/blob - SL/Controller/ShopOrder.pm
Merge branch 'master' of http://wagnertech.de/git/mfinanz
[mfinanz.git] / SL / Controller / ShopOrder.pm
1 package SL::Controller::ShopOrder;
2
3 use strict;
4
5 use parent qw(SL::Controller::Base);
6
7 use SL::BackgroundJob::ShopOrderMassTransfer;
8 use SL::System::TaskServer;
9 use SL::DB::ShopOrder;
10 use SL::DB::ShopOrderItem;
11 use SL::DB::Shop;
12 use SL::DB::History;
13 use SL::DBUtils;
14 use SL::Shop;
15 use SL::Helper::Flash;
16 use SL::Locale::String;
17 use SL::Controller::Helper::ParseFilter;
18 use Rose::Object::MakeMethods::Generic
19 (
20   'scalar --get_set_init' => [ qw(shop_order shops transferred js) ],
21 );
22
23 __PACKAGE__->run_before('check_auth');
24 __PACKAGE__->run_before('setup');
25
26 use Data::Dumper;
27
28 sub action_get_orders {
29   my ( $self ) = @_;
30   my $orders_fetched;
31   my $new_orders;
32
33   my $type = $::form->{type};
34   if ( $type eq "get_next" ) {
35     my $active_shops = SL::DB::Manager::Shop->get_all(query => [ obsolete => 0 ]);
36     foreach my $shop_config ( @{ $active_shops } ) {
37       my $shop = SL::Shop->new( config => $shop_config );
38
39       $new_orders = $shop->connector->get_new_orders;
40       push @{ $orders_fetched }, $new_orders ;
41     }
42
43   } elsif ( $type eq "get_one" ) {
44     my $shop_id = $::form->{shop_id};
45     my $shop_ordernumber = $::form->{shop_ordernumber};
46
47     if ( $shop_id && $shop_ordernumber ){
48       my $shop_config = SL::DB::Manager::Shop->get_first(query => [ id => $shop_id, obsolete => 0 ]);
49       my $shop = SL::Shop->new( config => $shop_config );
50       unless ( SL::DB::Manager::ShopOrder->get_all_count( query => [ shop_ordernumber => $shop_ordernumber, shop_id => $shop_id, obsolete => 'f' ] )) {
51         my $connect = $shop->check_connectivity;
52         $new_orders = $shop->connector->get_one_order($shop_ordernumber);
53         push @{ $orders_fetched }, $new_orders ;
54       } else {
55         flash_later('error', t8('Shoporder "#2" From Shop "#1" is already fetched', $shop->config->description, $shop_ordernumber));
56       }
57     } else {
58         flash_later('error', t8('Shop or ordernumber not selected.'));
59     }
60   }
61
62   foreach my $shop_fetched(@{ $orders_fetched }) {
63     if($shop_fetched->{error}){
64       flash_later('error', t8('From shop "#1" :  #2 ', $shop_fetched->{shop_description}, $shop_fetched->{message},));
65     }else{
66       flash_later('info', t8('From shop #1 :  #2 shoporders have been fetched.', $shop_fetched->{shop_description}, $shop_fetched->{number_of_orders},));
67     }
68   }
69
70   $self->redirect_to(controller => "ShopOrder", action => 'list', filter => { 'transferred:eq_ignore_empty' => 0, obsolete => 0 });
71 }
72
73 sub action_list {
74   my ( $self ) = @_;
75
76   my %filter = ($::form->{filter} ? parse_filter($::form->{filter}) : query => [ transferred => 0, obsolete => 0 ]);
77   my $transferred = $::form->{filter}->{transferred_eq_ignore_empty} ne '' ? $::form->{filter}->{transferred_eq_ignore_empty} : '';
78   my $sort_by = $::form->{sort_by} ? $::form->{sort_by} : 'order_date';
79   $sort_by .=$::form->{sort_dir} ? ' DESC' : ' ASC';
80   my $shop_orders = SL::DB::Manager::ShopOrder->get_all( %filter, sort_by => $sort_by,
81                                                       with_objects => ['shop_order_items', 'kivi_customer', 'shop'],
82                                                     );
83
84   foreach my $shop_order(@{ $shop_orders }){
85     $shop_order->{open_invoices} = $shop_order->check_for_open_invoices;
86   }
87   $self->_setup_list_action_bar;
88   $self->render('shop_order/list',
89                 title       => t8('ShopOrders'),
90                 SHOPORDERS  => $shop_orders,
91                 TOOK        => $transferred,
92               );
93 }
94
95 sub action_show {
96   my ( $self ) = @_;
97   my $id = $::form->{id} || {};
98   my $shop_order = SL::DB::ShopOrder->new( id => $id )->load( with => ['kivi_customer'] );
99   die "can't find shoporder with id $id" unless $shop_order;
100
101   my $proposals = $shop_order->check_for_existing_customers;
102
103   $self->render('shop_order/show',
104                 title       => t8('Shoporder'),
105                 IMPORT      => $shop_order,
106                 PROPOSALS   => $proposals,
107               );
108
109 }
110
111 sub action_customer_assign_to_shoporder {
112   my ($self) = @_;
113
114   $self->shop_order->assign_attributes( kivi_customer => $::form->{customer} );
115   $self->shop_order->save;
116   $self->redirect_to(controller => "ShopOrder", action => 'show', id => $self->shop_order->id);
117 }
118
119 sub action_delete_order {
120   my ( $self ) = @_;
121
122   $self->shop_order->obsolete(1);
123   $self->shop_order->save;
124   $self->redirect_to(controller => "ShopOrder", action => 'list', filter => { 'transferred:eq_ignore_empty' => 0 });
125 }
126
127 sub action_undelete_order {
128   my ( $self ) = @_;
129
130   $self->shop_order->obsolete(0);
131   $self->shop_order->save;
132   $self->redirect_to(controller => "ShopOrder", action => 'list', filter => { 'transferred:eq_ignore_empty' => 0, obsolete => 0 });
133 }
134
135 sub action_transfer {
136   my ( $self ) = @_;
137
138   $::form->{customer} ||= $::form->{partial_transfer_customer_id};
139
140   my $customer = SL::DB::Manager::Customer->find_by(id => $::form->{customer});
141   die "Can't find customer" unless ref $customer eq 'SL::DB::Customer';
142
143   my $employee = SL::DB::Manager::Employee->current;
144   die "Can't find employee" unless $employee;
145
146   die "Can't load shop_order form form->import_id" unless $self->shop_order;
147   my $order = $self->shop_order->convert_to_sales_order(customer => $customer, employee => $employee,
148                                                         pos_ids  => $::form->{pos_ids}               );
149
150   if ($order->{error}){
151     flash_later('error',@{$order->{errors}});
152     $self->redirect_to(controller => "ShopOrder", action => 'show', id => $self->shop_order->id);
153   }else{
154     $order->db->with_transaction( sub {
155       $order->calculate_prices_and_taxes;
156       $order->save;
157       SL::DB::OrderVersion->new(oe_id => $order->id, version => 1)->save;
158
159       my $snumbers = "ordernumber_" . $order->ordnumber;
160       SL::DB::History->new(
161                         trans_id    => $order->id,
162                         snumbers    => $snumbers,
163                         employee_id => SL::DB::Manager::Employee->current->id,
164                         addition    => 'SAVED',
165                         what_done   => 'Shopimport -> Order',
166                       )->save();
167       foreach my $item(@{ $order->orderitems }){
168         $item->parse_custom_variable_values->save;
169         $item->{custom_variables} = \@{ $item->cvars_by_config };
170         $item->save;
171       }
172
173       $self->shop_order->transferred(1);
174       $self->shop_order->transfer_date(DateTime->now_local);
175       $self->shop_order->save;
176       $self->shop_order->link_to_record($order);
177     }) || die $order->db->error;
178     $self->redirect_to(controller => 'Order', action => 'edit', type => 'sales_order', vc => 'customer', id => $order->id);
179   }
180 }
181
182 sub action_mass_transfer {
183   my ($self) = @_;
184   my @shop_orders =  @{ $::form->{id} || [] };
185
186   my $job                   = SL::DB::BackgroundJob->new(
187     type                    => 'once',
188     active                  => 1,
189     package_name            => 'ShopOrderMassTransfer',
190   )->set_data(
191      shop_order_record_ids       => [ @shop_orders ],
192      num_order_created           => 0,
193      num_order_failed            => 0,
194      num_delivery_order_created  => 0,
195      status                      => SL::BackgroundJob::ShopOrderMassTransfer->WAITING_FOR_EXECUTION(),
196      conversion_errors         => [],
197    )->update_next_run_at;
198
199    SL::System::TaskServer->new->wake_up;
200
201    my $html = $self->render('shop_order/_transfer_status', { output => 0 }, job => $job);
202
203    $self->js
204       ->html('#status_mass_transfer', $html)
205       ->run('kivi.ShopOrder.massTransferStarted')
206       ->render;
207 }
208
209 sub action_transfer_status {
210   my ($self)  = @_;
211   my $job     = SL::DB::BackgroundJob->new(id => $::form->{job_id})->load;
212   my $html    = $self->render('shop_order/_transfer_status', { output => 0 }, job => $job);
213
214   $self->js->html('#status_mass_transfer', $html);
215   $self->js->run('kivi.ShopOrder.massTransferFinished') if $job->data_as_hash->{status} == SL::BackgroundJob::ShopOrderMassTransfer->DONE();
216   $self->js->render;
217
218 }
219
220 sub action_apply_customer {
221   my ( $self, %params ) = @_;
222   my $shop = SL::DB::Manager::Shop->find_by( id => $self->shop_order->shop_id );
223   my $what = $::form->{create_customer}; # new from billing, customer or delivery address
224   my %address = ( 'name'                  => $::form->{$what.'_name'},
225                   'department_1'          => $::form->{$what.'_company'},
226                   'department_2'          => $::form->{$what.'_department'},
227                   'street'                => $::form->{$what.'_street'},
228                   'zipcode'               => $::form->{$what.'_zipcode'},
229                   'city'                  => $::form->{$what.'_city'},
230                   'email'                 => $::form->{$what.'_email'},
231                   'country'               => $::form->{$what.'_country'},
232                   'phone'                 => $::form->{$what.'_phone'},
233                   'email'                 => $::form->{$what.'_email'},
234                   'greeting'              => $::form->{$what.'_greeting'},
235                   'taxincluded_checked'   => $shop->pricetype eq "brutto" ? 1 : 0,
236                   'taxincluded'           => $shop->pricetype eq "brutto" ? 1 : 0,
237                   'pricegroup_id'         => (split '\/',$shop->price_source)[0] eq "pricegroup" ?  (split '\/',$shop->price_source)[1] : undef,
238                   'taxzone_id'            => $shop->taxzone_id,
239                   'currency'              => $::instance_conf->get_currency_id,
240                   #'payment_id'            => 7345,# TODO hardcoded
241                 );
242   my $customer;
243   if($::form->{cv_id}){
244     $customer = SL::DB::Customer->new(id => $::form->{cv_id})->load;
245     $customer->assign_attributes(%address);
246     $customer->save;
247   }else{
248     $customer = SL::DB::Customer->new(%address);
249     $customer->save;
250   }
251   my $snumbers = "customernumber_" . $customer->customernumber;
252   SL::DB::History->new(
253                     trans_id    => $customer->id,
254                     snumbers    => $snumbers,
255                     employee_id => SL::DB::Manager::Employee->current->id,
256                     addition    => 'SAVED',
257                     what_done   => 'Shopimport',
258                   )->save();
259
260   $self->redirect_to(action => 'show', id => $::form->{import_id});
261 }
262
263 sub setup {
264   my ($self) = @_;
265   $::auth->assert('shop_part_edit');
266   $::request->layout->use_javascript("${_}.js")  for qw(kivi.ShopOrder);
267 }
268
269 sub check_auth {
270   $::auth->assert('shop_part_edit');
271 }
272 #
273 # Helper
274 #
275
276 sub init_shop_order {
277   my ( $self ) = @_;
278   return SL::DB::ShopOrder->new(id => $::form->{import_id})->load if $::form->{import_id};
279 }
280
281 sub init_transferred {
282   [ { title => t8("all"),             value => '' },
283     { title => t8("transferred"),     value => 1  },
284     { title => t8("not transferred"), value => 0  }, ]
285 }
286
287 sub init_shops {
288   SL::DB::Shop->shops_dd;
289 }
290
291 sub _setup_list_action_bar {
292   my ($self) = @_;
293
294   for my $bar ($::request->layout->get('actionbar')) {
295     $bar->add(
296         action => [
297           t8('Search'),
298           submit    => [ '#shoporders', { action => "ShopOrder/list" } ],
299         ],
300         combobox => [
301           link => [
302             t8('Shoporders'),
303             call    => [ 'kivi.ShopOrder.get_orders_next' ],
304             tooltip => t8('New shop orders'),
305           ],
306           action => [
307             t8('Get one order'),
308             call    => [ 'kivi.ShopOrder.get_one_order_setup', id => "get_one" ],
309             tooltip => t8('Get one order by shopordernumber'),
310           ],
311         ],
312         'separator',
313         action => [
314           t8('Execute'),
315           call => [ 'kivi.ShopOrder.setup', id => "mass_transfer" ],
316           tooltip => t8('Transfer all marked'),
317         ],
318     );
319   }
320 }
321
322 1;
323
324 __END__
325
326 =encoding utf-8
327
328 =head1 NAME
329
330 SL::Controller::ShopOrder - Shoporder CRUD Controller
331
332 =head1 DESCRIPTION
333
334 Fetches the shoporders and transfers them to orders.
335
336 Relations for shoporders
337
338 =over 2
339
340 =item shop_order_items
341
342 =item shops
343
344 =item shop_parts
345
346 =back
347
348 =head1 URL ACTIONS
349
350 =over 4
351
352 =item C<action_get_orders>
353
354 Fetches the shoporders with the shopconnector class
355
356 =item C<action_list>
357
358 List the shoporders by different filters.
359 From the List you can transfer shoporders into orders in batch where it is possible or one by one.
360
361 =item C<action_show>
362
363 Shows one order. From here you can apply/change/select customer data and transfer the shoporder to an order.
364
365 =item C<action_delete>
366
367 Marks the shoporder as obsolete. It's for shoporders you don't want to transfer.
368
369 =item C<action_undelete>
370
371 Marks the shoporder obsolete = false
372
373 =item C<action_transfer>
374
375 Transfers one shoporder to an order.
376 If the optional  $::form->{pos_ids} exists, they will be added
377 as a param for the convert_to_sales_order method
378
379 =item C<action_apply_customer>
380
381 Applys a new customer from the shoporder.
382
383 =back
384
385 =head1 TASKSERVER ACTIONS
386
387 =over 4
388
389 =item C<action_mass_transfer>
390
391 Transfers more shoporders by backgroundjob called from the taskserver to orders.
392
393 =item C<action_transfer_status>
394
395 Shows the backgroundjobdata for the popup status window
396
397 =back
398
399 =head1 SETUP
400
401 =over 4
402
403 =item C<setup>
404
405 =back
406
407 =head1 INITS
408
409 =over 4
410
411 =item C<init_shoporder>
412
413 =item C<init_transfered>
414
415 Transferstatuses for the filter dropdown
416
417 =item C<init_shops>
418
419 Filter dropdown Shops
420
421 =back
422
423 =head1 TODO
424
425 Implements different payments, pricesources and pricegroups. Till now not needed.
426
427 =head1 BUGS
428
429 None yet. :)
430
431 =head1 AUTHOR
432
433 W. Hahn E<lt>wh@futureworldsearch.netE<gt>
434
435 =cut