Merge branch 'ticket-12462-returnMR' into develop

This commit is contained in:
Marion Muszynski 2017-02-21 14:25:07 +01:00
commit 208f2e2476
2 changed files with 393 additions and 1 deletions

View File

@ -136,6 +136,229 @@ class AdminOrders extends AdminTab
$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
}
elseif(Tools::isSubmit('submitCreateReturn')) {
$id_order = (int) Tools::getValue('id_order');
if(Validate::isLoadedObject($order = new Order($id_order)) && ($address_delivery = Db::getInstance()->getRow('
SELECT *
FROM `'._DB_PREFIX_.'address`
WHERE `id_address` = '.(int) $order->id_address_delivery.'
')) && in_array((int) $address_delivery['id_country'], array(3, 6, 8, 12))) {
$returnable = array();
foreach(Db::getInstance()->ExecuteS('
SELECT d.`id_order_detail`, d.`id_order`, d.`product_name`, d.`product_quantity_return`, d.`product_quantity_refunded`, d.`product_quantity`, c.`id_sale`, d.`product_weight`
FROM `'._DB_PREFIX_.'order_detail` d
LEFT JOIN `'._DB_PREFIX_.'product_ps_cache` c
ON d.`product_id` = c.`id_product`
WHERE d.`id_order` = '.(int) $order->id.'
') as $product) {
$qty = OrderReturn::getOrderDetailReturnQty($product);
if($qty > 0) {
$returnable[$product['id_order_detail']] = array($product['product_name'], $qty, $product['product_weight']);
}
}
}
$error = FALSE;
$total_weight = 0.0;
$return_reasons = array();
foreach(Tools::getValue('return_product') as $id_order_detail => $qty) {
if(!isset($returnable[(int) $id_order_detail]) || $returnable[(int) $id_order_detail][1] < $qty) {
$error = TRUE;
} else {
for($i = 1; $i <= $qty; $i++) {
if(!($return_reason = Tools::getValue('return_reason_'.$id_order_detail.'_'.$i))) {
$error = true;
$this->_errors[] = Tools::displayError('Order detail #%s empty return reason');
} elseif(!($return_instruction = Tools::getValue('return_instruction_'.$id_order_detail.'_'.$i))) {
$error = true;
$this->_errors[] = Tools::displayError('Order detail #%s empty return instruction');
} else {
$return_reasons[] = array($id_order_detail, $i, $return_reason, $return_instruction);
}
}
$total_weight += $qty * $returnable[(int) $id_order_detail][2];
}
}
if(!$error) {
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'order_return`
VALUES (
DEFAULT,
'.(int) $order->id_customer.',
'.(int) $order->id.',
2,
"'.''/* QUESTION */.'",
NOW(),
NOW()
)
');
$id_order_return = Db::getInstance()->Insert_ID();
foreach($return_reasons as $return_reason) {
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'order_return_detail_qty` (`id_order_return`, `id_order_detail`, `qty`, `reason`, `instruction`)
VALUES (
'.(int) $id_order_return.',
'.(int) $return_reason[0].',
'.(int) $return_reason[1].',
'.(int) $return_reason[2].',
'.(int) $return_reason[3].'
)
');
}
$product_list = '<ul>';
$product_list_txt = array();
foreach(Tools::getValue('return_product') as $id_order_detail => $qty) {
if($qty > 0) {
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'order_return_detail`
VALUES (
'.(int) $id_order_return.',
'.(int) $id_order_detail.',
0,
'.(int) $qty.'
)
');
$product_name = Db::getInstance()->getValue('
SELECT `product_name`
FROM `'._DB_PREFIX_.'order_detail`
WHERE `id_order_detail` = '.(int) $id_order_detail.'
');
$product_list_txt[] = (int) $qty.' x '.$product_name;
$product_list .= '<li>'.(int) $qty.' x '.htmlentities($product_name).'</li>';
}
}
$product_list .= '</ul>';
if($order->id_lang == 3) {
// Spain
if((int) Tools::getValue('return_option') == 2) {
// Free
$pcode = '11';
$chars = array('I', 'O', 'P', 'S', 'T', );
$return_link = 'http://devoluciones.puntopack.es/d/F1BEBEBO/?SiteId=F1BEBEBO&Country=ES&Language=es';
} else {
// Paid
$pcode = '08';
$chars = array('A', 'E', 'K', 'R', 'Z', );
$return_link = 'http://devoluciones.puntopack.es/d/F1BEBEBO/?SiteId=F1BEBEBO4&Country=ES&Language=es';
}
} else {
if((int) $address_delivery['id_country'] == 3) {
// Belgium
if((int) Tools::getValue('return_option') == 2) {
// Free
$pcode = '36';
$chars = array('K', 'P', 'T', 'S', 'W', 'Z', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO&Country=BE&Language=fr';
} else {
// Paid
$pcode = '24';
$chars = array('C', 'J', 'L', 'M', 'N', 'R', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO5&Country=BE&Language=fr';
}
} elseif((int) $address_delivery['id_country'] == 6) {
// Spain
if((int) Tools::getValue('return_option') == 2) {
// Free
$pcode = '11';
$chars = array('I', 'O', 'P', 'S', 'T', );
$return_link = 'http://devoluciones.puntopack.es/d/F1BEBEBO/?SiteId=F1BEBEBO&Country=ES&Language=fr';
} else {
// Paid
$pcode = '08';
$chars = array('A', 'E', 'K', 'R', 'Z', );
$return_link = 'http://devoluciones.puntopack.es/d/F1BEBEBO/?SiteId=F1BEBEBO4&Country=ES&Language=fr';
}
} elseif((int) $address_delivery['id_country'] == 8) {
// France
if((int) Tools::getValue('return_option') == 2) {
// Free
$pcode = '05';
$chars = array('L', 'J', 'R', 'N', 'W', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO&Country=FR&Language=fr';
} else {
// Paid
$pcode = '01';
$chars = array('B', 'C', 'D', 'G', 'V', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO6&Country=FR&Language=fr';
}
} elseif((int) $address_delivery['id_country'] == 12) {
// Luxemburg
if((int) Tools::getValue('return_option') == 2) {
// Free
$pcode = '05';
$chars = array('L', 'J', 'R', 'N', 'W', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO&Country=LU&Language=fr';
} else {
// Paid
$pcode = '01';
$chars = array('B', 'C', 'D', 'G', 'V', );
$return_link = 'http://retours.mondialrelay.com/d/F1BEBEBO/?SiteId=F1BEBEBO6&Country=LU&Language=fr';
}
}
}
Db::getInstance()->Execute('SET AUTOCOMMIT = 0');
Db::getInstance()->Execute('START TRANSACTION');
$cpt = Db::getInstance()->ExecuteS('
SELECT `number`
FROM `'._DB_PREFIX_.'order_return_link_number`
WHERE `carrier` = "mondialrelay"
FOR UPDATE
');
$cpt = (int) $cpt[0]['number'] + 1;
Db::getInstance()->ExecuteS('
UPDATE `'._DB_PREFIX_.'order_return_link_number`
SET `number` = '.(int) $cpt.'
WHERE `carrier` = "mondialrelay"
');
Db::getInstance()->Execute('COMMIT');
Db::getInstance()->Execute('SET AUTOCOMMIT = 1');
$cpt = sprintf('%06d', $cpt);
$return_number = 'R'.substr($cpt, 0, 2).chr(65 + rand(0, 25)).substr($cpt, 2, 2).$chars[rand(0, count($chars) - 1)].substr($cpt, 4, 2).'P'.$pcode.substr($pcode, 0, 1).substr($cpt, 5, 1).substr($pcode, 1, 1);
$return_link .= '&Email='.rawurlencode(Db::getInstance()->getValue('
SELECT `email`
FROM `'._DB_PREFIX_.'customer`
WHERE `id_customer` = '.(int) $order->id_customer.'
')).'&CustomReference='.$return_number.'&Adress1='.rawurlencode($address_delivery['lastname']).'&Adress2='.rawurlencode($address_delivery['firstname']).'&Adress3='.rawurlencode($address_delivery['address1']).'&Adress4='.rawurlencode($address_delivery['address2']).'&PostCode='.rawurlencode($address_delivery['postcode']).'&City='.rawurlencode($address_delivery['city']).'&WeightInGramm='.((int) ($total_weight * 1000));
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'order_return_link`
VALUES (
'.(int) $id_order_return.',
'.(int) $cookie->id_employee.',
NOW(),
'.((int) Tools::getValue('return_option') == 2? 1: 0).',
0,
"mondialrelay",
"'.pSQL($return_number).'",
"'.pSQL($return_link).'",
"'.pSQL(nl2br2(strip_tags(trim(Tools::getValue('return_comment')))), TRUE).'"
)
');
$subject = array(
1 => 'Your order return #'.$id_order_return,
2 => 'Votre demande de retour n°'.$id_order_return,
3 => 'Solicitud de devolución n°'.$id_order_return,
5 => 'La vostra domanda di restituzione #'.$id_order_return,
6 => 'Your order return #'.$id_order_return,
);
$customer = new Customer($order->id_customer);
Mail::Send(
intval($order->id_lang),
'order_return_'.((int) Tools::getValue('return_option') == 2? '2': '3'),
$subject[(int) $order->id_lang],
array(
'{id_order}' => $order->id,
'{return_link}' => $return_link,
'{product_list}' => $product_list,
'{product_list_txt}' => implode("\r\n", $product_list_txt),
),
$customer->email,
$customer->firstname.' '.$customer->lastname
);
}
header('Location: '.$_SERVER['REQUEST_URI']);
exit;
}
/* Change order state, add a new entry in order history and send an e-mail to the customer if needed */
elseif (Tools::isSubmit('submitState') AND ($id_order = (int)(Tools::getValue('id_order'))) AND Validate::isLoadedObject($order = new Order($id_order)))
{
@ -511,6 +734,15 @@ class AdminOrders extends AdminTab
$sent_logistics[(int) $row['id_order_detail']] = (int) $row['quantity'];
}
foreach(Db::getInstance()->ExecuteS('
SELECT SUM(`quantity`) AS `quantity`, `id_order_detail`
FROM `'._DB_PREFIX_.'mondialrelay_parcel`
WHERE `id_order_detail` IN ('.implode(', ', array_keys($parcel_quantities)).')
GROUP BY `id_order_detail`
') as $row) {
$sent_logistics[(int) $row['id_order_detail']] = (int) $row['quantity'];
}
foreach(Db::getInstance()->ExecuteS('
SELECT SUM(`quantity`) AS `quantity`, `id_order_detail`
FROM `'._DB_PREFIX_.'exapaqws`
@ -989,6 +1221,23 @@ class AdminOrders extends AdminTab
</div>
<div class="clear">&nbsp;</div>';
$product_psale = array();
$products_ids = array();
foreach(Db::getInstance()->ExecuteS('
SELECT DISTINCT `product_id`
FROM `'._DB_PREFIX_.'order_detail`
WHERE `id_order` = '.(int) $order->id.'
') as $row) {
$products_ids[] = (int) $row['product_id'];
}
foreach(Db::getInstance()->ExecuteS('
SELECT *
FROM `'._DB_PREFIX_.'product_ps_cache`
WHERE `id_product` IN ('.implode(', ', $products_ids).')
') as $row) {
$product_psale[(int) $row['id_product']] = (int) $row['id_sale'];
}
// List of products
echo '
<a name="products"><br /></a>
@ -1222,9 +1471,118 @@ class AdminOrders extends AdminTab
foreach ($returns as $return)
{
$state = new OrderReturnState($return['state']);
/* Mondial relay return */
$return_link = FALSE;
if($state->id == 2) {
$return_link = Db::getInstance()->getRow('
SELECT `return_number`, `link`
FROM `'._DB_PREFIX_.'order_return_link`
WHERE `id_order_return` = '.(int) $return['id_order_return'].'
');
}
echo '('.Tools::displayDate($return['date_upd'], $cookie->id_lang).') :
<b><a href="index.php?tab=AdminReturn&id_order_return='.$return['id_order_return'].'&updateorder_return&token='.Tools::getAdminToken('AdminReturn'.(int)(Tab::getIdFromClassName('AdminReturn')).(int)($cookie->id_employee)).'">'.$this->l('#').sprintf('%06d', $return['id_order_return']).'</a></b> -
'.$state->name[$cookie->id_lang].'<br />';
'.$state->name[$cookie->id_lang].'<br />'.($return_link? ' ('.$this->l('return link:').' <a href="'.$return_link['link'].'" onclick="window.open(this.href); return false;">'.$return_link['return_number'].'</a>)': '');
}
if(in_array($addressDelivery->id_country, array(3, 6, 8, 12))) {
$returnable = array();
foreach ($products as $k => $product) {
$product['id_sale'] = $product_psale[(int) $product['product_id']];
$qty = OrderReturn::getOrderDetailReturnQty($product);
if($qty > 0) {
$returnable[$product['id_order_detail']] = array($product['product_name'], $qty);
}
}
if(count($returnable) > 0) {
$instructions = array(
1 => 'Remboursement',
2 => 'Remboursement + voir la personne qui a crée l\'étiquette',
3 => 'Voir la personne qui a crée l\'étiquette',
4 => 'Réexpédition échange',
5 => 'Mise en stock',
);
$reasons = array(
// 1 => 'CLIENT : Annulation pré-envoi',
2 => 'CLIENT : Rétractation post-envoi',
11 => 'CLIENT : Annulation pour ré-achat',
4 => 'FEUR : Problème SAV',
5 => 'FEUR : Produit manquant',
3 => 'BBB : Erreur Achat / Prod',
6 => 'BBB : Erreur Logistique ',
8 => 'BBB : Pbme Site / Paiment',
12 => 'BBB : Suspicion de fraude',
9 => 'TRANS : Colis détruit',
10 => 'TRANS : Colis perdu',
7 => 'Autre'
);
echo '<script type="text/javascript">
$(document).ready(function() {
$(".return_input").change(function() {
var id_order_detail = $(this).attr("data-order-detail");
var qty = parseInt($(this).val());
var max = parseInt($(this).attr("max"));
if(qty == 0) {
$(".return_" + id_order_detail).hide();
}
for(var j = 1; j <= max; j=j+1) {
var id = "#return_" + id_order_detail + "_" + j;
if(j <= qty) {
$(id).show();
} else {
$(id).hide();
}
}
});
$(".return_input").trigger("change");
});
</script>
<br /><br />
<h4>'.$this->l('Create a product return').'</h4>
<form id="new_product_return" action="" method="post">
<ul style="list-style: outside none; margin: 0; padding: 0;">';
foreach($returnable as $id_order_detail => $product) {
echo '
<li style="padding: 5px; background: #eee;"><input data-order-detail="'.(int) $id_order_detail.'" class="return_input" style="width: 30px; text-align: right; border: 1px solid #E0D0B1; padding: 2px 4px;" type="number" name="return_product['.(int) $id_order_detail.']" value="0" autocomplete="off" step="1" max="'.(int) $product[1].'" min="0" /> x '.$product[0]. '</li>
<li id="reason_'.$id_order_detail.'">';
for($i = 1; $i <= $product[1]; $i++) {
echo '<p id="return_'.(int) $id_order_detail.'_'.$i.'">
<label style="margin: 0px; padding: 0px; float: none; text-align: left; font-weight: normal; display: block; margin-bottom: 5px;">'.sprintf($this->l('Return reason product #%s'), $i).'</label>
<select autocomplete="off" name="return_reason_'.(int) $id_order_detail.'_'.$i.'">';
foreach($reasons as $id_reason => $label) {
echo '<option value="'.$id_reason.'">'.$label.'</option>';
}
echo '</select><br />
<label style="margin: 0px; padding: 0px; float: none; text-align: left; font-weight: normal;display: block; margin-bottom: 5px;">'.sprintf($this->l('Return instruction product #%s'), $i).'</label>
<select autocomplete="off" name="return_instruction_'.(int) $id_order_detail.'_'.$i.'">';
foreach($instructions as $id_instruction => $label) {
echo '<option value="'.$id_instruction.'">'.$this->l($label).'</option>';
}
echo '</select>
</p><br />';
}
echo '</li>';
}
echo '</ul>
<p>
<label for="return_option" style="margin: 0px; padding: 0px; float: none; text-align: left; font-weight: normal;">'.$this->l('This return will be').'</label>
<select autocomplete="off" name="return_option" id="return_option">
<option value="1">'.$this->l('paid by the customer').'</option>
<option value="2">'.$this->l('free').'</option>
</select>
</p>
<p>
<label style="width: auto; margin-bottom: 5px;">'.$this->l('Insert a comment (optional):').'</label>
<textarea name="return_comment" rows="5" cols="50" style="resize: vertical"></textarea>
</p>
<p class="submit"><input type="submit" value="'.$this->l('Confirm').'" name="submitCreateReturn" class="button" /></p>
</form>';
} else {
echo '<br /><br /><p class="warning">'.$this->l('No product can currently be returned on this order').'</p>';
}
}
echo '</fieldset>';

View File

@ -0,0 +1,34 @@
<?php
class OrderReturn extends OrderReturnCore {
public static function getOrderDetailReturnQty($product) {
if(Db::getInstance()->getRow('
SELECT `id_order`
FROM `'._DB_PREFIX_.'shipping_history`
WHERE `id_order` = '.(int) $product['id_order'].'
AND `id_sale` = '.(int) $product['id_sale'].'
')) {
$qty = (int) $product['product_quantity'] - max((int) $product['product_quantity_refunded'], (int) $product['product_quantity_return']);
} else {
$qty = (int) Db::getInstance()->getValue('
SELECT SUM(`quantity`)
FROM `'._DB_PREFIX_.'lapostews`
WHERE `id_order_detail` = '.(int) $product['id_order_detail'].'
') + (int) Db::getInstance()->getValue('
SELECT SUM(`quantity`)
FROM `'._DB_PREFIX_.'mondialrelay_parcel`
WHERE `id_order_detail` = '.(int) $product['id_order_detail'].'
') - max($product['product_quantity_return'], $product['product_quantity_refunded']);
}
$qty -= (int) Db::getInstance()->getValue('
SELECT SUM(d.`product_quantity`)
FROM `'._DB_PREFIX_.'order_return_detail` d
LEFT JOIN `'._DB_PREFIX_.'order_return` r
ON d.`id_order_return` = r.`id_order_return`
WHERE d.`id_order_detail` = '.(int) $product['id_order_detail'].'
AND r.`state` < 3
');
return $qty;
}
}