0
1
Fork 0

Edi load fixes

This commit is contained in:
Juan Ferrer 2019-05-24 15:30:48 +02:00
parent 4f3b7efcb3
commit fb422846dd
10 changed files with 177 additions and 506 deletions

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.406.47) stable; urgency=low
hedera-web (1.406.48) stable; urgency=low
* Initial Release.

View File

@ -1,6 +1,6 @@
{
"name": "hedera-web",
"version": "1.406.47",
"version": "1.406.48",
"description": "Verdnatura web page",
"license": "GPL-3.0",
"repository": {

View File

@ -6,7 +6,7 @@ class Clean extends Edi\Method {
function ediRun($db) {
$imap = $this->imap;
$cleanPeriod = $db->getValue('SELECT clean_period FROM imap_config');
$cleanPeriod = $db->getValue('SELECT cleanPeriod FROM imapConfig');
$deleted = 0;
$date = new DateTime(NULL);
@ -14,8 +14,8 @@ class Clean extends Edi\Method {
$filter = sprintf('BEFORE "%s"', $date->format('D, j M Y'));
$folders = [
$this->imapConf['success_folder']
,$this->imapConf['error_folder']
$this->imapConf['successFolder']
,$this->imapConf['errorFolder']
];
foreach ($folders as $folder)
@ -36,7 +36,7 @@ class Clean extends Edi\Method {
echo "Total $deleted mails deleted\n";
echo "Deleting records from database\n";
$db->query('DELETE FROM message WHERE created < #', [$date]);
$db->query('DELETE FROM mail WHERE created < #', [$date]);
echo "Done\n";
}
}

View File

@ -1,169 +0,0 @@
/**
* Adds a new lot, generates its barcode
* inserts/updates de record on table #vn2008.buy_edi
**/
USE edi;
DROP PROCEDURE IF EXISTS batch_new;
DELIMITER $$
CREATE PROCEDURE batch_new (
v_message INT
,v_type MEDIUMINT
,v_delivery_number BIGINT
,v_fec DATE
,v_hor TIME
,v_ref INT
,v_agj INT
,v_cat VARCHAR(2)
,v_pac INT
,v_sub MEDIUMINT
,v_kop INT
,v_ptd VARCHAR(6)
,v_pro MEDIUMINT
,v_ori VARCHAR(3)
,v_ptj MEDIUMINT
,v_qty INT
,v_pri DOUBLE
,v_klo SMALLINT
,v_s1 VARCHAR(3)
,v_s2 VARCHAR(3)
,v_s3 VARCHAR(3)
,v_s4 VARCHAR(4)
,v_s5 VARCHAR(3)
,v_s6 VARCHAR(3)
,v_k1 SMALLINT
,v_k2 SMALLINT
,v_p1 TINYINT
,v_p2 TINYINT
,v_auction SMALLINT
,v_package INT
)
BEGIN
DECLARE v_edi INT;
DECLARE v_barcode CHAR(15) DEFAULT NULL;
DECLARE v_is_duplicated BOOLEAN DEFAULT FALSE;
DECLARE v_update_existent BOOLEAN DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR 1062 -- ER_DUP_KEY
SET v_is_duplicated = TRUE;
-- Genera el código de barras
IF v_agj != 0 AND v_agj IS NOT NULL
THEN
SET v_barcode = CONCAT(
LPAD(v_auction, 2, 0),
LPAD(IFNULL(v_klo, 99), 2, 0),
LPAD(DAYOFYEAR(v_fec), 3, 0),
IF(v_klo IS NULL OR v_klo = 99,
LPAD(v_agj, 7, 0),
CONCAT(LPAD(v_agj, 5, 0), '01')
),
'0'
);
END IF;
IF v_kop IS NULL
THEN
SELECT default_kop INTO v_kop FROM config;
END IF;
-- Inserta el nuevo EKT
INSERT INTO vn2008.buy_edi SET
barcode = IFNULL(v_barcode, barcode)
,delivery_number = v_delivery_number
,entry_year = YEAR(v_fec)
,fec = v_fec
,hor = v_hor
,ref = v_ref
,agj = v_agj
,cat = v_cat
,pac = v_pac
,sub = v_sub
,kop = v_kop
,ptd = v_ptd
,pro = v_pro
,ori = v_ori
,ptj = v_ptj
,qty = v_qty
,pri = v_pri
,klo = v_klo
,s1 = v_s1
,s2 = v_s2
,s3 = v_s3
,s4 = v_s4
,s5 = v_s5
,s6 = v_s6
,k01 = v_k1
,k02 = v_k2
,k03 = v_p1
,k04 = v_p2
,auction = v_auction
,package = v_package;
-- Si el EKT está duplicado y el que habia en la tabla era uno
-- provisional, lo actualiza con los nuevos valores.
IF NOT v_is_duplicated
THEN
SET v_edi = LAST_INSERT_ID();
CALL edi_load (v_edi);
ELSEIF v_delivery_number != 0
AND v_delivery_number IS NOT NULL
THEN
SELECT id INTO v_edi
FROM vn2008.buy_edi
WHERE delivery_number = v_delivery_number;
SELECT COUNT(*) = 0 INTO v_update_existent
FROM vn2008.buy_edi e
JOIN batch b ON b.buy_edi_id = e.id
JOIN config c
WHERE e.delivery_number = v_delivery_number
AND b.type_id != c.presale_id;
END IF;
IF v_update_existent
THEN
UPDATE vn2008.buy_edi SET
barcode = IFNULL(v_barcode, barcode)
,fec = v_fec
,hor = v_hor
,ref = v_ref
,agj = v_agj
,cat = v_cat
,pac = v_pac
,sub = v_sub
,kop = v_kop
,ptd = v_ptd
,pro = v_pro
,ori = v_ori
,ptj = v_ptj
,qty = v_qty
,pri = v_pri
,klo = v_klo
,s1 = v_s1
,s2 = v_s2
,s3 = v_s3
,s4 = v_s4
,s5 = v_s5
,s6 = v_s6
,k01 = v_k1
,k02 = v_k2
,k03 = v_p1
,k04 = v_p2
,auction = v_auction
,package = v_package
WHERE id = v_edi;
END IF;
-- Registra el lote
INSERT INTO batch SET
message_id = v_message
,type_id = v_type
,buy_edi_id = v_edi;
END$$
DELIMITER ;

View File

@ -1,164 +0,0 @@
/**
* Creates a buy line from an EDI lot.
*
* @param v_edi The EDI id
**/
USE edi;
DROP PROCEDURE IF EXISTS edi_load;
DELIMITER $$
CREATE PROCEDURE edi_load (v_edi INT)
BEGIN
DECLARE v_ref INT;
DECLARE v_buy INT;
DECLARE v_item INT;
DECLARE v_qty INT;
DECLARE v_package INT;
DECLARE v_is_lot BOOLEAN;
-- Carga los datos necesarios del EKT
SELECT ref, qty, package INTO v_ref, v_qty, v_package
FROM vn2008.buy_edi e
LEFT JOIN item i ON e.ref = i.id
WHERE e.id = v_edi;
-- Inserta el cubo si no existe
IF v_package = 800
THEN
SET v_package = 800 + v_qty;
INSERT IGNORE INTO vn2008.Cubos SET
Id_Cubo = v_package,
x = 7200 / v_qty,
y = 1;
ELSE
INSERT IGNORE INTO vn2008.Cubos (Id_Cubo, X, Y, Z)
SELECT bucket_id, ROUND(x_size/10), ROUND(y_size/10), ROUND(z_size/10)
FROM bucket WHERE bucket_id = v_package;
IF ROW_COUNT() > 0
THEN
INSERT INTO vn2008.mail SET
`subject` = 'Cubo añadido',
`text` = CONCAT('Se ha añadido el cubo: ', v_package),
`to` = 'ekt@verdnatura.es';
END IF;
END IF;
-- Intenta obtener el artículo en base a los atributos holandeses
INSERT IGNORE INTO item_track SET
item_id = v_ref;
SELECT c.Id_Compra, c.Id_Article INTO v_buy, v_item
FROM vn2008.buy_edi e
JOIN item_track t ON t.item_id = e.ref
LEFT JOIN vn2008.buy_edi l ON l.ref = e.ref
LEFT JOIN vn2008.Compres c ON c.buy_edi_id = l.id
JOIN vn2008.config cfg
WHERE e.id = v_edi
AND l.id != v_edi
AND c.Id_Article != cfg.generic_item
AND IF(t.s1, l.s1 = e.s1, TRUE)
AND IF(t.s2, l.s2 = e.s2, TRUE)
AND IF(t.s3, l.s3 = e.s3, TRUE)
AND IF(t.s4, l.s4 = e.s4, TRUE)
AND IF(t.s5, l.s5 = e.s5, TRUE)
AND IF(t.s6, l.s6 = e.s6, TRUE)
AND IF(t.kop, l.kop = e.kop, TRUE)
AND IF(t.pac, l.pac = e.pac, TRUE)
AND IF(t.cat, l.cat = e.cat, TRUE)
AND IF(t.ori, l.ori = e.ori, TRUE)
AND IF(t.pro, l.pro = e.pro, TRUE)
AND IF(t.sub, l.sub = e.sub, TRUE)
AND IF(t.package, l.package = e.package, TRUE)
AND c.Id_Article < 170000
ORDER BY l.now DESC, c.Id_Compra ASC LIMIT 1;
-- Determina si el articulo se vende por lotes
IF v_item
THEN
SELECT COUNT(*) > 0 INTO v_is_lot
FROM vn2008.Articles a
LEFT JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
WHERE a.Id_Article = v_item
AND t.`transaction`;
-- Si el articulo se vende por lotes se inserta un nuevo artículo
IF v_is_lot
THEN
INSERT INTO vn2008.Articles (
Article
,Medida
,Categoria
,Id_Origen
,iva_group_id
,Foto
,Color
,Codintrastat
,tipo_id
,Tallos
)
SELECT
i.`name`
,IFNULL(e.s1, e.pac)
,e.cat
,IFNULL(o.id, 17)
,IFNULL(a.iva_group_id, 1)
,a.Foto
,a.Color
,a.Codintrastat
,IFNULL(a.tipo_id, 10)
,IF(a.tipo_id = 15, 0, 1)
FROM vn2008.buy_edi e
LEFT JOIN item i ON i.id = e.ref
LEFT JOIN vn2008.Origen o ON o.Abreviatura = e.ori
LEFT JOIN vn2008.Articles a ON a.Id_Article = v_item
WHERE e.id = v_edi;
SET v_item = LAST_INSERT_ID();
END IF;
END IF;
-- Inserta la compra asociada al EKT
INSERT INTO vn2008.Compres
(
Id_Entrada
,buy_edi_id
,Costefijo
,Id_Article
,Nicho
,`grouping`
,caja
,Packing
,Cantidad
,Productor
,Etiquetas
,Id_Cubo
)
SELECT
cfg.edi_entry
,v_edi
,(@t := IF(a.Tallos, a.Tallos, 1)) * e.pri
,IFNULL(v_item, cfg.generic_item)
,a.Nicho
,IFNULL(c.`grouping`, e.pac)
,IFNULL(c.caja, TRUE)
,@pac := e.pac / @t
,@pac * e.qty
,s.company_name
,e.qty
,IFNULL(c.Id_Cubo, e.package)
FROM vn2008.buy_edi e
LEFT JOIN vn2008.Compres c ON c.Id_Compra = v_buy
LEFT JOIN vn2008.Articles a ON a.Id_Article = c.Id_Article
LEFT JOIN supplier s ON e.pro = s.supplier_id
JOIN vn2008.config cfg
WHERE e.id = v_edi
LIMIT 1;
END$$
DELIMITER ;

View File

@ -1,27 +0,0 @@
/**
* Registers an email.
*
* @param v_mail_id Message-ID of email
* @param v_sender Origin email id
**/
USE edi;
DROP PROCEDURE IF EXISTS message_new;
DELIMITER $$
CREATE PROCEDURE message_new (
v_mail_id VARCHAR(100)
,v_sender VARCHAR(150)
,OUT v_message_id INT
)
BEGIN
DECLARE v_sender_id INT;
SELECT id INTO v_sender_id FROM mail
WHERE mail = v_sender;
INSERT IGNORE INTO message SET
sender_id = v_sender_id
,mail_id = v_mail_id;
SET v_message_id = LAST_INSERT_ID();
END$$
DELIMITER ;

View File

@ -13,7 +13,7 @@ abstract class Method extends \Vn\Lib\Method {
$db->selectDb('edi');
$imapConf = $db->getRow(
'SELECT host, user, pass, success_folder, error_folder FROM imap_config');
'SELECT host, user, pass, successFolder, errorFolder FROM imapConfig');
$this->mailbox = sprintf('{%s/imap/ssl/novalidate-cert}',
$imapConf['host']);

View File

@ -12,8 +12,10 @@ class Load extends Edi\Method {
if (!$this->ediSchema)
throw new Exception('Can not load EDI schema.');
$this->restrictToSenders = $db->getValue(
"SELECT restrictToSenders FROM exchangeConfig LIMIT 1");
$this->params = $db->query(
'SELECT code, name, subname, position, type, required FROM param');
"SELECT code, name, subname, position, type, required FROM param");
$inbox = imap_search($this->imap, 'ALL');
@ -24,7 +26,7 @@ class Load extends Edi\Method {
$inboxCount = count($inbox);
if ($inboxCount > 0)
echo "Total $inboxCount messages readed\n";
echo "Total $inboxCount messages processed.\n";
}
}
@ -33,151 +35,180 @@ class Load extends Edi\Method {
// Gets EKT messages from email
$msgStructure = imap_fetchstructure($imap, $msg);
$result = [];
// Gets the mail sender and Message-ID
$header = imap_headerinfo($imap, $msg);
$from = $header->from;
if (property_exists($header, 'message_id'))
$mailId = trim($header->message_id, '<>');
else
$mailId = NULL;
if ($from && count($from) > 0)
$sender = $from[0]->mailbox .'@'. $from[0]->host;
else
$sender = NULL;
// Searches the EDI message on mail parts
$matchTypes = [TYPEAPPLICATION, TYPETEXT];
$this->imapFindParts($msgStructure, $matchTypes, [], $result);
$count = 0;
$error = NULL;
foreach ($result as $msgSection)
try {
$part = imap_bodystruct($imap, $msg, $msgSection);
$ediString = imap_fetchbody($imap, $msg, $msgSection);
$msgStructure = imap_fetchstructure($imap, $msg);
$result = [];
// Gets the mail sender and Message-ID
switch ($part->encoding) {
case ENCBASE64:
$ediString = imap_base64($ediString);
break;
case ENCQUOTEDPRINTABLE:
$ediString = imap_qprint($ediString);
break;
}
$header = imap_headerinfo($imap, $msg);
$from = $header->from;
if (!Edi\Message::isEdiString($ediString))
continue;
// Creates the EDI object and loads its exchanges
if (property_exists($header, 'message_id'))
$messageId = trim($header->message_id, '<>');
else
$messageId = NULL;
$ediMessage = new Edi\Message();
$ediMessage->parse($ediString, $this->ediSchema);
if ($from && count($from) > 0)
$sender = $from[0]->mailbox .'@'. $from[0]->host;
else
$sender = NULL;
$db->query('START TRANSACTION');
$db->query('CALL messageNew(#mailId, #sender, @message)',
[
'mailId' => $mailId,
$db->query('CALL mail_new(#messageId, #sender, @mailFk)', [
'messageId' => $messageId,
'sender' => $sender
]);
$unb = $ediMessage->section;
$unhs = $unb->childs['UNH'];
foreach ($unhs as $unh)
foreach ($lins = $unh->childs['LIN'] as $lin) {
$ediValues = [];
// Gets the exchange params
$mailId = $db->getValue("SELECT @mailFk");
$this->params->data_seek(0);
echo "Message from: $sender\n";
echo " -> Message id: $messageId\n";
while ($row = $this->params->fetch_assoc()) {
switch ($row['type']) {
case 'INTEGER':
$type = Type::INTEGER;
break;
case 'DOUBLE':
$type = Type::DOUBLE;
break;
case 'DATE':
$type = Type::DATE;
break;
case 'TIME':
$type = Type::TIME;
break;
default:
$type = Type::STRING;
}
$value = $lin->getValue(
$row['name'], $row['position'], $type, $row['subname']);
if (!isset($value) && $row['required'])
throw new Exception('Missing required parameter: '. $row['code']);
$ediValues[$row['code']] = $value;
}
// Gets the exchange features
$res = $db->query(
'SELECT presentation_order, feature
FROM item_feature
WHERE item_id = #ref
AND entry_date <= CURDATE()
AND(expiry_date IS NULL OR expiry_date >= CURDATE())
GROUP BY presentation_order'
,$ediValues
if ($this->restrictToSenders) {
$isAllowed = $db->getValue(
"SELECT COUNT(*) > 0 FROM mailSender WHERE mail = #",
[$sender]
);
if ($res)
while ($row = $res->fetch_assoc()) {
$value = $lin->getValue('IMD', 2, Type::INTEGER, $row['feature']);
$ediValues['s'.$row['presentation_order']] = $value;
}
else
throw new Exception('Can\'t get the item features.');
for ($i = 1; $i <= 6; $i++)
if (!isset($ediValues['s'.$i]))
$ediValues['s'.$i] = NULL;
// Adds the exchange to the Database
$res = $db->queryFromFile(__DIR__.'/sql/batch-add', $ediValues);
if (!$res)
throw new Exception('Failed to insert the line.');
$count++;
if (!$isAllowed)
throw new Exception('Mail processing from unknown senders is disabled');
}
// Searches the EDI message on mail parts
$matchTypes = [TYPEAPPLICATION, TYPETEXT];
$this->imapFindParts($msgStructure, $matchTypes, [], $result);
$count = 0;
$error = NULL;
foreach ($result as $msgSection)
try {
$part = imap_bodystruct($imap, $msg, $msgSection);
$ediString = imap_fetchbody($imap, $msg, $msgSection);
switch ($part->encoding) {
case ENCBASE64:
$ediString = imap_base64($ediString);
break;
case ENCQUOTEDPRINTABLE:
$ediString = imap_qprint($ediString);
break;
}
if (!Edi\Message::isEdiString($ediString))
continue;
// Creates the EDI object and loads its exchanges
$ediMessage = new Edi\Message();
$ediMessage->parse($ediString, $this->ediSchema);
$db->query('START TRANSACTION');
$unb = $ediMessage->section;
$unhs = $unb->childs['UNH'];
foreach ($unhs as $unh)
foreach ($lins = $unh->childs['LIN'] as $lin) {
$ediValues = ['mailId' => $mailId];
// Gets the exchange params
$this->params->data_seek(0);
while ($row = $this->params->fetch_assoc()) {
switch ($row['type']) {
case 'INTEGER':
$type = Type::INTEGER;
break;
case 'DOUBLE':
$type = Type::DOUBLE;
break;
case 'DATE':
$type = Type::DATE;
break;
case 'TIME':
$type = Type::TIME;
break;
default:
$type = Type::STRING;
}
$value = $lin->getValue(
$row['name'], $row['position'], $type, $row['subname']);
if (!isset($value) && $row['required'])
throw new Exception('Missing required parameter: '. $row['code']);
$ediValues[$row['code']] = $value;
}
// Gets the exchange features
$res = $db->query(
'SELECT presentation_order, feature
FROM item_feature
WHERE item_id = #ref
AND entry_date <= CURDATE()
AND(expiry_date IS NULL OR expiry_date >= CURDATE())
GROUP BY presentation_order'
,$ediValues
);
if ($res)
while ($row = $res->fetch_assoc()) {
$value = $lin->getValue('IMD', 2, Type::INTEGER, $row['feature']);
$ediValues['s'.$row['presentation_order']] = $value;
}
else
throw new Exception('Can\'t get the item features.');
for ($i = 1; $i <= 6; $i++)
if (!isset($ediValues['s'.$i]))
$ediValues['s'.$i] = NULL;
// Adds the exchange to the Database
$res = $db->queryFromFile(__DIR__.'/sql/exchange-new', $ediValues);
if (!$res)
throw new Exception('Failed to insert the line.');
$count++;
}
$db->query('COMMIT');
} catch (Exception $e) {
$db->query('ROLLBACK');
throw $e;
}
if ($count == 0)
throw new Exception('No part with EDI format was found');
echo " -> Mail id: $mailId\n";
echo " -> Loaded exchanges: $count\n";
$folder = $this->imapConf['successFolder'];
$db->query(
"UPDATE mail
SET nExchanges = #,
error = NULL
WHERE id = #",
[$count, $mailId]
);
$db->query('COMMIT');
} catch (Exception $e) {
$db->query('ROLLBACK');
$error = $e->getMessage();
break;
}
if (!$error && $count == 0)
$error = 'EDI messages not found.';
error_log($error);
// Logs information of realized operations
if (!$error) {
$folder = $this->imapConf['success_folder'];
echo "Mail loaded with $count lines.\n";
} else {
$folder = $this->imapConf['error_folder'];
echo "Mail error: $error\n";
$folder = $this->imapConf['errorFolder'];
$db->query(
"UPDATE mail
SET error = #
WHERE id = #",
[$error, $mailId]
);
}
// Moves the mail to another folder

View File

@ -1,5 +1,5 @@
CALL batchNew (
@message, #art, #bgm, #aaj, #fec, #hor, #ref, #agj, #cat, #pac,
CALL exchange_new (
#mailId, #art, #bgm, #aaj, #fec, #hor, #ref, #agj, #cat, #pac,
#sub, #kop, #ptd, #pro, #ori, #ptj, #qty, #pri, #klo, #s1, #s2, #s3,
#s4, #s5, #s6, #k1, #k2, #p1, #p2, #auction, #package, #putOrderFk
)

View File

@ -3,13 +3,13 @@
class Update extends Vn\Lib\Method {
function run($db) {
$db->selectDb('edi');
//$db->options(MYSQLI_OPT_LOCAL_INFILE, TRUE);
$db->getHandler()->options(MYSQLI_OPT_LOCAL_INFILE, TRUE);
$tmpDir = '/tmp/floricode';
// Establish the FTP connection
$ftpConf = $db->getRow('SELECT host, user, password FROM ftp_config');
$ftpConf = $db->getRow('SELECT host, user, password FROM ftpConfig');
echo "Openning FTP connection to {$ftpConf['host']}\n";
$ftpConn = ftp_connect($ftpConf['host']);
@ -25,7 +25,7 @@ class Update extends Vn\Lib\Method {
set_time_limit(0);
$res = $db->query(
'SELECT file_name, to_table, file, updated FROM file_config');
'SELECT fileName, toTable, file, updated FROM fileConfig');
$dwFiles = [];
@ -35,8 +35,8 @@ class Update extends Vn\Lib\Method {
while ($row = $res->fetch_assoc())
try {
$file = $row['file'];
$table = $row['to_table'];
$baseName = $row['file_name'];
$table = $row['toTable'];
$baseName = $row['fileName'];
if ($row['updated']) {
$updated = DateTime::createFromFormat('Y-m-d', $row['updated']);
@ -95,7 +95,7 @@ class Update extends Vn\Lib\Method {
$db->query("START TRANSACTION");
$db->query("DELETE FROM {$db->quote($table)}");
$db->queryFromFile(__DIR__."/sql/$table", ['file' => $fileName]);
$db->query("UPDATE file_config SET updated = # WHERE file_name = #",
$db->query("UPDATE fileConfig SET updated = # WHERE fileName = #",
[$lastUpdated, $baseName]
);
$db->query("COMMIT");