1 package SL::Controller::ShopOrder;
5 use parent qw(SL::Controller::Base);
7 use SL::BackgroundJob::ShopOrderMassTransfer;
8 use SL::System::TaskServer;
10 use SL::DB::ShopOrderItem;
15 use SL::Helper::Flash;
16 use SL::Locale::String;
17 use SL::Controller::Helper::ParseFilter;
18 use Rose::Object::MakeMethods::Generic
20 'scalar --get_set_init' => [ qw(shop_order shops transferred js) ],
23 __PACKAGE__->run_before('check_auth');
24 __PACKAGE__->run_before('setup');
28 sub action_get_orders {
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 );
39 $new_orders = $shop->connector->get_new_orders;
40 push @{ $orders_fetched }, $new_orders ;
43 } elsif ( $type eq "get_one" ) {
44 my $shop_id = $::form->{shop_id};
45 my $shop_ordernumber = $::form->{shop_ordernumber};
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 ;
55 flash_later('error', t8('Shoporder "#2" From Shop "#1" is already fetched', $shop->config->description, $shop_ordernumber));
58 flash_later('error', t8('Shop or ordernumber not selected.'));
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},));
66 flash_later('info', t8('From shop #1 : #2 shoporders have been fetched.', $shop_fetched->{shop_description}, $shop_fetched->{number_of_orders},));
70 $self->redirect_to(controller => "ShopOrder", action => 'list', filter => { 'transferred:eq_ignore_empty' => 0, obsolete => 0 });
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'],
84 foreach my $shop_order(@{ $shop_orders }){
85 $shop_order->{open_invoices} = $shop_order->check_for_open_invoices;
87 $self->_setup_list_action_bar;
88 $self->render('shop_order/list',
89 title => t8('ShopOrders'),
90 SHOPORDERS => $shop_orders,
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;
101 my $proposals = $shop_order->check_for_existing_customers;
103 $self->render('shop_order/show',
104 title => t8('Shoporder'),
105 IMPORT => $shop_order,
106 PROPOSALS => $proposals,
111 sub action_customer_assign_to_shoporder {
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);
119 sub action_delete_order {
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 });
127 sub action_undelete_order {
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 });
135 sub action_transfer {
138 $::form->{customer} ||= $::form->{partial_transfer_customer_id};
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';
143 my $employee = SL::DB::Manager::Employee->current;
144 die "Can't find employee" unless $employee;
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} );
150 if ($order->{error}){
151 flash_later('error',@{$order->{errors}});
152 $self->redirect_to(controller => "ShopOrder", action => 'show', id => $self->shop_order->id);
154 $order->db->with_transaction( sub {
155 $order->calculate_prices_and_taxes;
157 SL::DB::OrderVersion->new(oe_id => $order->id, version => 1)->save;
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,
165 what_done => 'Shopimport -> Order',
167 foreach my $item(@{ $order->orderitems }){
168 $item->parse_custom_variable_values->save;
169 $item->{custom_variables} = \@{ $item->cvars_by_config };
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);
182 sub action_mass_transfer {
184 my @shop_orders = @{ $::form->{id} || [] };
186 my $job = SL::DB::BackgroundJob->new(
189 package_name => 'ShopOrderMassTransfer',
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;
199 SL::System::TaskServer->new->wake_up;
201 my $html = $self->render('shop_order/_transfer_status', { output => 0 }, job => $job);
204 ->html('#status_mass_transfer', $html)
205 ->run('kivi.ShopOrder.massTransferStarted')
209 sub action_transfer_status {
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);
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();
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
243 if($::form->{cv_id}){
244 $customer = SL::DB::Customer->new(id => $::form->{cv_id})->load;
245 $customer->assign_attributes(%address);
248 $customer = SL::DB::Customer->new(%address);
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,
257 what_done => 'Shopimport',
260 $self->redirect_to(action => 'show', id => $::form->{import_id});
265 $::auth->assert('shop_part_edit');
266 $::request->layout->use_javascript("${_}.js") for qw(kivi.ShopOrder);
270 $::auth->assert('shop_part_edit');
276 sub init_shop_order {
278 return SL::DB::ShopOrder->new(id => $::form->{import_id})->load if $::form->{import_id};
281 sub init_transferred {
282 [ { title => t8("all"), value => '' },
283 { title => t8("transferred"), value => 1 },
284 { title => t8("not transferred"), value => 0 }, ]
288 SL::DB::Shop->shops_dd;
291 sub _setup_list_action_bar {
294 for my $bar ($::request->layout->get('actionbar')) {
298 submit => [ '#shoporders', { action => "ShopOrder/list" } ],
303 call => [ 'kivi.ShopOrder.get_orders_next' ],
304 tooltip => t8('New shop orders'),
308 call => [ 'kivi.ShopOrder.get_one_order_setup', id => "get_one" ],
309 tooltip => t8('Get one order by shopordernumber'),
315 call => [ 'kivi.ShopOrder.setup', id => "mass_transfer" ],
316 tooltip => t8('Transfer all marked'),
330 SL::Controller::ShopOrder - Shoporder CRUD Controller
334 Fetches the shoporders and transfers them to orders.
336 Relations for shoporders
340 =item shop_order_items
352 =item C<action_get_orders>
354 Fetches the shoporders with the shopconnector class
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.
363 Shows one order. From here you can apply/change/select customer data and transfer the shoporder to an order.
365 =item C<action_delete>
367 Marks the shoporder as obsolete. It's for shoporders you don't want to transfer.
369 =item C<action_undelete>
371 Marks the shoporder obsolete = false
373 =item C<action_transfer>
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
379 =item C<action_apply_customer>
381 Applys a new customer from the shoporder.
385 =head1 TASKSERVER ACTIONS
389 =item C<action_mass_transfer>
391 Transfers more shoporders by backgroundjob called from the taskserver to orders.
393 =item C<action_transfer_status>
395 Shows the backgroundjobdata for the popup status window
411 =item C<init_shoporder>
413 =item C<init_transfered>
415 Transferstatuses for the filter dropdown
419 Filter dropdown Shops
425 Implements different payments, pricesources and pricegroups. Till now not needed.
433 W. Hahn E<lt>wh@futureworldsearch.netE<gt>