1 # Copyright 2002-2008 Interchange Development Group and others
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version. See the LICENSE file for details.
8 # $Id: update_order_status.tag,v 1.13 2008-06-26 12:43:44 mheins Exp $
10 UserTag update-order-status Order order_number
11 UserTag update-order-status addAttr
12 UserTag update-order-status Version $Revision: 1.13 $
13 UserTag update-order-status Routine <<EOR
16 #::logDebug("Shipping order number $on, opt=" . ::uneval($opt));
21 my $odb = database_exists_ref($opt->{orderline_table} || 'orderline')
22 or return $die->("No %s table!", 'orderline');
23 my $tdb = database_exists_ref($opt->{transactions_table} || 'transactions')
24 or return $die->("No %s table!", 'transactions');
25 my $udb = database_exists_ref($opt->{userdb_table} || 'userdb')
26 or return $die->("No %s table!", 'userdb');
28 my $trec = $tdb->row_hash($on);
31 return $die->("Bad transaction number: %s", $on);
34 my $user = $trec->{username};
36 if($udb->column_exists('email_copy')) {
37 $wants_copy = $udb->field($user, 'email_copy');
57 $opt->{$_} = $CGI::values{$_} if ! defined $opt->{$_};
60 my @track_keys = grep /tracking_number__1$/, keys %CGI::values;
64 $otracks[$1] = $CGI::values{$_};
67 $otracks[0] = $CGI::values{$_};
71 if($opt->{ship_all} == 2 or $opt->{void_transaction} or $opt->{cancel_order}) {
72 $opt->{cancel_order} = 1;
76 $opt->{archive} ||= $opt->{do_archive};
78 $wants_copy = $opt->{send_email} if length $opt->{send_email};
79 #Log("Order number=$on username=$user wants=$wants_copy");
80 delete $::Scratch->{ship_notice_username};
81 delete $::Scratch->{ship_notice_email};
83 $::Scratch->{ship_notice_username} = $user;
84 $::Scratch->{ship_notice_email} = $udb->field($user, 'email')
85 or delete $::Scratch->{ship_notice_username};
89 if($opt->{settle_transaction}) {
90 my $oid = $trec->{order_id};
91 my $amount = $trec->{total_cost};
95 name => 'settle_transaction',
96 set => "No order ID to settle!",
100 elsif($oid =~ /\*$/) {
102 name => 'settle_transaction',
103 set => "Order ID $oid already settled!",
108 #::logDebug("auth-code: $trec->{auth_code} oid=$oid");
109 my $settled = Vend::Tags->charge( {
110 route => $::Variable->{MV_PAYMENT_MODE},
113 auth_code => $trec->{auth_code},
114 transaction => 'settle_prior',
117 $tdb->set_field($on, 'order_id', "$oid*");
120 "Order ID %s settled with processor.",
127 name => 'settle_transaction',
129 "Order ID %s settle operation failed. Reason: %s",
131 $Vend::Session->{payment_result}{MErrMsg},
140 elsif($opt->{void_transaction}) {
141 my $oid = $trec->{order_id};
143 my $amount = $trec->{total_cost};
147 name => 'void_transaction',
148 set => "No order ID to void!",
152 elsif($oid =~ /-$/) {
154 name => 'void_transaction',
155 set => "Order ID $oid already voided!",
160 #::logDebug("auth-code: $trec->{auth_code} oid=$oid");
161 my $voided = Vend::Tags->charge( {
162 route => $::Variable->{MV_PAYMENT_MODE},
165 auth_code => $trec->{auth_code},
166 transaction => 'void',
169 $tdb->set_field($on, 'order_id', $oid . "-");
172 "Order ID %s voided.",
179 name => 'void_transaction',
181 "Order ID %s void operation failed. Reason: %s",
183 $Vend::Session->{payment_result}{MErrMsg},
193 if($opt->{status} =~ /\d\d\d\d/) {
194 $tdb->set_field($on, 'status', $opt->{status});
197 $tdb->set_field($on, 'status', 'shipped');
200 if($opt->{tracking_number} =~ /\w/) {
201 $tdb->set_field($on, 'tracking_number', $opt->{tracking_number});
206 if($opt->{lines_shipped}) {
207 @shiplines = grep /\S/, split /\0/, $opt->{lines_shipped};
213 if(! @shiplines and ! $opt->{ship_all}) {
214 my @keys = grep /status__1/, keys %CGI::values;
215 #::logDebug("keys to ship: " . join(',', @keys));
218 #::logDebug("examining $_");
220 m/^(\d+)_/ and $n = $1;
222 if($opt->{ship_all} or $CGI::values{$_} eq 'shipped') {
224 #::logDebug("ship $n");
227 undef $need_shiplines;
230 @shiplines = map { s/.*\D//; $_; } @shiplines;
233 my $count_q = "select * from orderline where order_number = '$on'";
234 my $lines_ary = $odb->query($count_q);
236 $::Scratch->{ui_message} = "No order lines for order $on";
239 my $total_lines = scalar @$lines_ary;
241 my $odb_keypos = $odb->config('KEY_INDEX');
243 # See if some items have already shipped
247 my $target_status = $opt->{cancel_order} ? 'canceled' : 'shipped';
251 my $code = $_->[$odb_keypos];
252 my $status = $odb->field($code, 'status');
254 $odb->set_field($code,'tracking_number',$otracks[$i]);
257 push @shiplines, $line if $need_shiplines;
260 if($status eq $target_status and ! $opt->{cancel_order}) {
263 elsif($opt->{ship_all}) {
264 $shipping{$line} = 1;
269 my $to_ship = scalar @shiplines;
271 #::logDebug("total_lines=$total_lines to_ship=$to_ship shiplines=" . uneval(\@shiplines));
276 @shiplines = grep ! $already{$_}, @shiplines;
277 @shipping{@shiplines} = @shiplines;
279 if($total_lines == $to_ship) {
280 $ship_mesg = "Order $on complete, $total_lines lines set shipped.";
281 $::Scratch->{ship_notice_complete} = $ship_mesg;
282 $g_status = $target_status;
285 $ship_mesg = "Order $on partially shipped ($to_ship of $total_lines lines).";
286 delete $::Scratch->{ship_notice_complete};
287 $g_status = 'partial';
292 my $email_mesg = $::Scratch->{ship_notice_username}
293 ? "Email copy sent to $::Scratch->{ship_notice_email}."
294 : "No email copy sent as per user preference.";
296 my $dotime = $odb->config('DSN');
298 $dotime = $dotime =~ /dbi:mysql:/ ? 0 : 1;
299 $update_date = POSIX::strftime('%Y-%m-%d %H:%M:%S %z', localtime());
301 # Actually update the orderline database
303 my $code = $_->[$odb_keypos];
306 next if $already{$line};
307 my $status = $shipping{$line} ? $target_status : 'backorder';
308 $odb->set_field($code, 'status', $status)
310 $::Scratch->{ui_message} = "Orderline $code ship status update failed.";
314 $odb->set_field($code, 'update_date', $update_date)
316 $::Scratch->{ui_message} = "Orderline $code ship date update failed.";
327 my $total_shipped_now = scalar keys %shipping;
329 delete $::Scratch->{ship_now_complete};
331 if($opt->{cancel_order}) {
332 $g_status = 'canceled';
333 $ship_mesg = "Order $on canceled.";
336 $total_lines != scalar @shiplines
338 $total_shipped_now == $total_lines
341 $g_status = 'shipped';
342 $::Scratch->{ship_now_complete} = 1
343 if $total_shipped_now == $total_lines;
344 $ship_mesg = "Order $on now complete (all $total_lines lines).";
347 $tdb->set_field($on, 'status', $g_status);
348 $tdb->set_field($on, 'archived', 1)
349 if $opt->{archive} and $g_status eq $target_status;
351 Vend::Tags->warning("$ship_mesg $email_mesg");
352 delete $::Scratch->{ship_notice_username};
353 delete $::Scratch->{ship_notice_email};
354 delete $::Scratch->{ship_notice_order_number};
356 $::Scratch->{ship_notice_order_number} = $on;
357 $::Scratch->{ship_notice_username} = $user;
358 $::Scratch->{ship_notice_email} = $trec->{email}
359 or delete $::Scratch->{ship_notice_username};
360 if($opt->{send_email}) {
361 my $filename = $opt->{ship_notice_template} || 'etc/ship_notice';
362 my $contents = $Tag->file($filename);
364 $contents = interpolate_html($contents);
365 $contents =~ s/^\s+//;
366 $contents =~ s/\s*$/\n/;
367 $Tag->email_raw({}, $contents);
371 errmsg("No ship_notice_template '%s' found", $filename),