224 lines
4.8 KiB
PHP
224 lines
4.8 KiB
PHP
<?php
|
|
|
|
require_once (__DIR__.'/lib/method.php');
|
|
require_once (__DIR__.'/lib/message.php');
|
|
|
|
use Vn\Lib\Type;
|
|
|
|
class Load extends Edi\Method
|
|
{
|
|
function ediRun ($db)
|
|
{
|
|
$this->ediSchema = Edi\Message::loadSchema ('CLOCKT');
|
|
|
|
if (!$this->ediSchema)
|
|
throw new Exception ('Can not load EDI schema.');
|
|
|
|
$this->params = $db->query (
|
|
'SELECT code, name, subname, position, type, required FROM param');
|
|
|
|
$inbox = imap_search ($this->imap, 'ALL');
|
|
|
|
if ($inbox)
|
|
{
|
|
foreach ($inbox as $msg)
|
|
$this->loadMail ($db, $msg);
|
|
|
|
$inboxCount = count ($inbox);
|
|
|
|
if ($inboxCount > 0)
|
|
echo "Total $inboxCount messages readed\n";
|
|
}
|
|
}
|
|
|
|
function loadMail ($db, $msg)
|
|
{
|
|
$imap = $this->imap;
|
|
|
|
// 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;
|
|
$mailId = trim ($header->message_id, '<>');
|
|
|
|
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);
|
|
|
|
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');
|
|
$db->query ('CALL messageNew (#mailId, #sender, @message)',
|
|
[
|
|
'mailId' => $mailId,
|
|
'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
|
|
|
|
$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/batch-add', $ediValues);
|
|
|
|
if (!$res)
|
|
throw new Exception ('Failed to insert the line.');
|
|
|
|
$count++;
|
|
}
|
|
|
|
$db->query ('COMMIT');
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
$db->query ('ROLLBACK');
|
|
$error = $e->getMessage ();
|
|
break;
|
|
}
|
|
|
|
if (!$error && $count == 0)
|
|
$error = 'EDI messages not found.';
|
|
|
|
// 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";
|
|
}
|
|
|
|
// Moves the mail to another folder
|
|
|
|
$folder = sprintf ('%s', $folder);
|
|
|
|
if (!imap_mail_move ($imap, $msg, $folder))
|
|
error_log ('Can\'t move message to %s: %s'
|
|
,$folder
|
|
,imap_last_error ()
|
|
);
|
|
}
|
|
|
|
function imapFindParts (&$part, &$matchTypes, $section, &$result)
|
|
{
|
|
if (in_array ($part->type, $matchTypes))
|
|
{
|
|
if (count ($section) > 0)
|
|
$result[] = implode ('.', $section);
|
|
else
|
|
$result[] = '1';
|
|
}
|
|
elseif ($part->type == TYPEMULTIPART)
|
|
foreach ($part->parts as $i => $subpart)
|
|
{
|
|
array_push ($section, $i + 1);
|
|
$this->imapFindParts ($subpart, $matchTypes, $section, $result);
|
|
array_pop ($section);
|
|
}
|
|
}
|
|
}
|
|
|