Commit 788c72c2 authored by Danny Froberg's avatar Danny Froberg 💬
Browse files

Working for new and upd sorting

parent cd2ab316
{
"name": "dfroberg/bolistparser",
"type": "project",
"description": "Retrieve and parse FINFO Bolist files.",
"keywords": [
"finfo",
"bolist"
],
"license": "MIT",
"require": {
"php": "^7.1.3",
"hugsbrugs/php-sftp": "1.0"
}
}
<?php
/**
* FINFO Bolist Format
*/
$field_len = 0+(mb_strlen( "\r\n"));
$field_head = Array("Faltnamn","Beskrivning","Startpos","Langd","Dec","Datatyp");
$field_desc = Array(
......@@ -70,3 +73,42 @@ $field_desc = Array(
Array('BOLTYP','Kod lager/beställningsvara eller tillverkning','715','1',' ','AN'),
Array('BORESERV','Reserverat fält för framtida bruk 20','716','2','0','N'),
);
/**
* Kassanova Excel Import
*/
$excel_art_head = Array(
'head' => 'Ident;Namn;FilNamn;FilSokVag;FilTyp;FastPostlangd;AntalRaderPerPost;FaltSeparator;DecimalPunkt;KonvVarugrupp;KonvLeverantor;TypHuvudPost;TypRadPost;TypStartPost;TypSlutPost;SenasteGen;TextStartSlut;FilExtension;OMETillAnsi;Tabell;UpdUrsprung;UppdateringsTyp;Generell;UppdatMedExterntNr;RaknaUppArtikelNr;HittaArtMedLevArtNr;EnhetPaStreckkod;LevEnhetsTyp;Flik;Startrad',
'row' => 'EXCELART;Standard artikeliinläsning Excel;.xlsx;D:\data\infiler;E;0;1;;,;False;False;;;;;0;;xlsx;False;Artikel;;True;False;False;False;False;False;False;2;2'
);
$excel_art_row = Array(
'head' => 'Ident;KolumnId;KolumnTyp;Langd;StartPos;RadNr;AntalTanktaDec;FastVarde;AvvikDecPunkt;KonvStartPos;KopieraKolumn;KolumnSuffix;VBRegel;KolumnSuffixVBRegel',
'EXCELART;38;varchar;1;1;0;0;B;;0;0;0;0;0',
'EXCELART;73;fast;1;1;0;0;B;;0;0;0;0;0',
'EXCELART;74;varchar;19;1;1;0;;;1;0;0;0;0',
'EXCELART;1;varchar;19;1;2;0;;;2;74;0;11;0',
'EXCELART;7;varchar;19;1;3;0;;;3;0;0;0;0',
'EXCELART;5;varchar;6;1;4;0;;;4;0;0;0;0',
'EXCELART;6;varchar;15;1;5;0;;;5;0;0;0;0',
'EXCELART;3;varchar;35;1;6;0;;;6;0;0;0;0',
'EXCELART;4;varchar;35;1;7;0;;;7;0;0;0;0',
'EXCELART;8;varchar;20;1;8;0;;;8;0;0;0;0',
'EXCELART;2;varchar;13;1;9;0;;;9;0;0;0;0',
'EXCELART;22;varchar;5;1;10;0;ST;;10;0;0;2;0',
'EXCELART;23;varchar;5;1;11;0;;;11;22;0;1;0',
'EXCELART;15;money;10;1;12;0;;;12;0;0;0;0',
'EXCELART;9;numchar;10;1;13;0;;;13;15;0;1;0',
'EXCELART;11;numchar;10;1;14;0;1;;14;0;0;2;0',
'EXCELART;13;money;10;1;15;0;0;;15;0;0;2;0',
'EXCELART;65;varchar;6;1;16;0;;;16;0;0;0;0',
'EXCELART;135;varchar;10;1;17;0;;;17;0;0;0;0',
'EXCELART;137;varchar;10;1;18;0;;;18;0;0;0;0',
'EXCELART;17;numchar;2;1;19;0;1;;19;0;0;2;0',
'EXCELART;64;varchar;10;1;20;0;EXCEL;;20;0;0;2;0',
'EXCELART;31;numchar;5;1;21;0;1;;21;0;0;2;0',
'EXCELART;61;varchar;5;1;22;0;ST;;22;0;0;2;0',
'EXCELART;57;numchar;10;1;23;0;0;;23;0;0;2;0',
'EXCELART;58;varchar;5;1;24;0;;;24;0;0;0;0',
'EXCELART;112;numchar;10;1;25;0;;;25;31;0;1;0',
'EXCELART;111;varchar;5;1;26;0;;;26;61;0;1;0',
);
<?php
/**
* BoList File Parser
* Author: Danny Froberg <[email protected]>
* Copyright (C) 2019 All Rights Reserved.
*/
require_once "includes/definitions.php";
require_once 'includes/definitions.php';
require_once __DIR__ . '/vendor/autoload.php';
use Hug\Sftp\Sftp as Sftp;
/**
* Build unpack descriptor.
*
* @param $field_head
* @param $field_desc
*
......@@ -12,8 +18,8 @@ require_once "includes/definitions.php";
*/
function bulid_field_desc($field_head,$field_desc) {
global $field_len;
$field_len = 0+(mb_strlen( "\r\n"));
$fi = 0;
$field_len = 0+(mb_strlen( "\r\n")); // Reset on each build.
$fi = 0; // Fieldname Incrementor for RESERVED fields.
foreach ($field_desc as $key) {
switch($key[5]) {
case 'AN': $datatype = 'A'; break;
......@@ -25,39 +31,72 @@ function bulid_field_desc($field_head,$field_desc) {
$field .= $fi;
}
$descriptor[] = $datatype.$key[3].$field;
$field_len += $key[3];
$field_len += $key[3]; // Update global FINFO row length.
}
// var_dump( $descriptor );
return implode( '/', $descriptor);
}
/**
* Retrieve descriptor for a field.
*
* @param $field
*
* @return mixed
*/
function get_descriptor_details( $field ) {
global $field_desc;
return $field_desc[0][array_search( $field, $field_desc)];
return $field_desc[0][array_search( $field, $field_desc,true)];
}
/**
* Convert encoding.
*
* @param $item
*/
function myEncodeFunction(&$item)
{
$item = mb_convert_encoding($item, 'UTF-8', 'CP850');
}
function myEncodeFunctionANSI($item)
{
$item = mb_convert_encoding($item, 'UTF-8', 'Windows-1252');
return $item;
}
/**
* Display a field as price with decimals.
*
* @param $number
* @param int $decimals
*
* @return string
*/
function make_price($number,$decimals = 2) {
if($decimals > 0) {
return number_format( substr_replace( $number, '.', mb_strlen( $number ) - $decimals, 0 ), $decimals, ',', ' ' );
return number_format( substr_replace( $number, '.', mb_strlen( $number ) - $decimals, 0 ), $decimals, '.', '' );
} else {
return number_format( $number, $decimals, ',', '' );
return number_format( $number, $decimals, '.', '' );
}
}
/**
* @param $fields
* Processing per row of data.
*
* @param $f
*
* @return string
*/
function process_fields( $fields ) {
function process_fields( $f ) {
global $field_desc;
$i = 0;
echo $fields['BOPREAN'] . "\t" . $fields['BOARTL'] . "\t" . $fields['BOBNL1'] . "\t" .$fields['BOBNL2'] . "\t" . make_price($fields['BOPRIS'],2)."\t" . $fields['BOENH'] ."\t".make_price($fields['BOPC1'])."\n";
return $f['BOLNR'] . "\t" . $f['BOPREAN'] . "\t" . $f['BOARTL'] . "\t" . $f['BOBNL1'] . "\t" .$f['BOBNL2'] . "\t" . make_price($f['BOPRIS'],2)."\t" . $f['BOENH'] ."\t".make_price($f['BOPC1'])."\n";
}
/**
* Open and read data file.
*
* @param $file_name
*
* @return bool|string File content or false if failure.
*/
function get_file($file_name) {
$file_size = filesize( $file_name );
$file_desc = fopen( $file_name,'rb' ) or die ("can't open file");
......@@ -66,8 +105,16 @@ function get_file($file_name) {
return $file_buff;
}
/**
* Unpack and re-encode data and send each row to processing.
*
* @param $file_name
*
* @return string
*/
function parse($file_name) {
global $field_head, $field_desc, $field_len;
$buffer = '';
// Build Head
$descriptor = bulid_field_desc( $field_head, $field_desc );
// Read in file
......@@ -85,18 +132,357 @@ function parse($file_name) {
var_dump( $line );
exit();
}
echo sprintf( '%06d', $pretty_numbered_lines) ."\t";
$buffer .= sprintf( '%06d', $pretty_numbered_lines) ."\t";
$pretty_numbered_lines++;
process_fields( $line );
$buffer .= process_fields( $line );
}
/*
echo 'count: '.count( $field_desc )."\n";
echo 'lines: '.count( $file_chunks )."\n";
echo 'field len: '. $field_len."\n";
*/
return $buffer;
}
/**
* @param $f
*
* @return string
*/
function explain_field( $f ) {
global $field_desc;
foreach ($field_desc as $key) {
$field = $key[0];
if ($field === $f) {
return $key[1].' ('.$f.')';
}
}
}
/**
* @param $file_name
*
* @return int
*/
function identify_vilma_filter($file_name) {
global $field_head, $field_desc, $field_len;
$buffer = '';
// Build Head
$descriptor = bulid_field_desc( $field_head, $field_desc );
// Read in file
$file_buff = get_file($file_name);
$file_chunks = str_split($file_buff, $field_len);
$pretty_numbered_lines = 1;
$inpris = 0;
$baspris = 0;
$forspris = 0;
$caforspris = 0;
foreach ($file_chunks as $lines) {
// $buffer_conv = mb_convert_encoding($lines,'auto', 'CP850');
$line = unpack( $descriptor, $lines );
array_walk_recursive($line, 'myEncodeFunction');
$baspris += (float) make_price($line['BOPRIS']);
$inpris += (float) make_price($line['BONETPR']);
$forspris += (float) make_price($line['BOBRUPR']);
$caforspris += (float) make_price($line['BOPC1']);
//echo $line['BOARTL'].TAB.$line['BOPRIS'].TAB.$line['BONETPR'].TAB.$line['BOBRUPR']."\n";
}
var_dump( array( explain_field('BOPRIS') => $baspris, explain_field('BONETPR') => $inpris, explain_field('BOBRUPR') => $forspris, explain_field('BOPC1') => $caforspris ) );
if ( $baspris > 0 && $inpris > 0 && $forspris > 0 ) {
return 2;
} elseif ( $baspris > 0 && $inpris == 0 && $forspris == 0 ) {
return 3;
} elseif ( $baspris > 0 && $inpris > 0 && $forspris == 0 ) {
return 4;
} elseif ($baspris > 0 && $inpris == 0 && $forspris > 0 ) {
return 5;
} else {
return 1;
}
}
/**
* Parse directory for V*.txt import files.
*
* @param $path
*
* @return bool|string
*/
function parse_import_files_directory( $path ): string {
$result_buffer = '';
$directory = new RecursiveDirectoryIterator($path);
$iterator = new RecursiveIteratorIterator($directory);
$Regex = new RegexIterator($iterator, '/V.+\.TXT/i');
foreach($Regex as $files => $file) {
$result_buffer .= parse( $file->getPathname() );
}
if ( empty( $result_buffer) ) {
return false;
}
return $result_buffer;
}
// Test
parse('./tests/aaa_readfile.txt');
parse('./tests/V1412362.TXT');
parse('./tests/V1415377.TXT');
parse('./tests/V1414924.TXT');
parse('./tests/V1417312.TXT');
\ No newline at end of file
/**
* @return string
*/
function base_path() {
return __DIR__;
}
abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
protected $regex;
public function __construct(RecursiveIterator $it, $regex) {
$this->regex = $regex;
parent::__construct($it, $regex);
}
}
class FilenameFilter extends FilesystemRegexFilter {
// Filter files against the regex
public function accept() {
return ( ! $this->isFile() || preg_match($this->regex, $this->getFilename()));
}
}
class DirnameFilter extends FilesystemRegexFilter {
// Filter directories against the regex
public function accept() {
return ( ! $this->isDir() || preg_match($this->regex, $this->getFilename()));
}
}
/**
* Parse directory for T* FINFO description files.
*
* @param $path
*
* @return array|bool
*/
function parse_import_files_directory_descriptions( $path ): array {
$result_buffer = Array();
$directory = new RecursiveDirectoryIterator($path);
// Filter out ".Trash*" folders
$filter = new DirnameFilter($directory, '/^(?!\.Trash|\.|\..)/');
// Filter PHP/HTML files
// $filter = new FilenameFilter($filter, '/\.(?:php|html)$/');
$filter = new FilenameFilter($filter, '/T.+/i');
$iterator = new RecursiveIteratorIterator($filter);
$iterator->setMaxDepth(0); // 2 deep
foreach($iterator as $files => $file) {
$result_buffer[] = $file->getPathname();
}
if ( count( $result_buffer ) < 1 ) {
return array('error' => count( $result_buffer ).' files found');
}
return $result_buffer;
}
/**
* Parse description file for attributes.
*/
function parse_desc_file( $filename ) {
$handle = fopen( $filename, 'r');
$path = pathinfo($filename);
$filesize = filesize( $filename);
$buffer = myEncodeFunctionANSI( fread( $handle, $filesize ) );
fclose( $handle );
$curr = 0;
// Do the assignments.
$match[$curr]['filename'] = $filename;
preg_match_all('/^Filnamn:(\s+)(.*)$/um', $buffer, $matches);
$match[$curr]['zipfil'] = $path['dirname'].'\\'.@trim($matches[2][0]).'.zip';
$match[$curr]['filesize'] = filesize($match[$curr]['zipfil']);
preg_match_all('/^Filtyp:(\s+)(\w+)$/um', $buffer, $matches);
$match[$curr]['filtyp'] = @trim($matches[2][0]);
//var_dump( $matches);
preg_match_all('/^Beställt via:(\s+)(\w+)$/um', $buffer, $matches);
$match[$curr]['ordertyp'] = @trim($matches[2][0]);
//var_dump( $matches);
preg_match_all('/^Antal nya Vilmaartiklar, som har tillkommit.(\s+)(\d+)$/um', $buffer, $matches);
$match[$curr]['nya'] = 0 + @(int) $matches[2][0];
preg_match_all('/^Leverantör:(\s+)(\d+)(\s+)(.*)$/um', $buffer, $matches);
$match[$curr]['levnr'] = @trim($matches[2][0]);
$match[$curr]['levname'] = @trim($matches[4][0]);
if(!isset( $matches[2][0] ) && !isset( $matches[4][0] ) ) {
preg_match_all('/^Leverantörs-id:(\s+)(\d+)$/um', $buffer, $matches);
$match[$curr]['levnr'] = @trim($matches[2][0]);
preg_match_all('/^Leverantörsnamn:(\s+)(.*)$/um', $buffer, $matches);
$match[$curr]['levname'] = @trim($matches[2][0]);
}
return $match;
}
/**
* @return bool
*/
function sync_sftp_directory() {
ini_set('display_errors', 1);
ini_set('error_reporting', E_ALL);
ini_set('max_execution_time', 0);
$FtpServer = 'sftp2.logiq.no';
$FtpPort = 2222;
$FtpUser = 'f40054';
$FtpPass = 'Vwre5yHj';
$FtpPath = '/';
$remote_dir = '/2customer/';
$local_dir = "P:/FINFO_Import/";
# Scan Directory
$test = Sftp::scandir($FtpServer, $FtpUser, $FtpPass, $remote_dir, $FtpPort);
$downloads = false;
foreach ( $test as $file ) {
$downloads = Sftp::download( $FtpServer, $FtpUser, $FtpPass, $remote_dir.'/'.$file, $local_dir.'/'.$file, $FtpPort );
}
return $downloads;
}
/**
* Generate all the reciever directories.
*/
function setup_reciever_directories() {
$directory['base'] = 'P:/FINFO_Import/';
$directory['nyabol'] = $directory['base'].'bolist_nya';
$directory['nyabol3'] = $directory['base'].'bolist_nya/vilma_3';
$directory['nyabol5'] = $directory['base'].'bolist_nya/vilma_5';
$directory['updbol'] = $directory['base'].'bolist_upd';
$directory['updbol3'] = $directory['base'].'bolist_upd/vilma_3';
$directory['updbol5'] = $directory['base'].'bolist_upd/vilma_5';
$directory['other'] = $directory['base'].'other';
foreach ($directory as $local_dir ) {
if ( ! is_dir( $local_dir ) ) {
if ( ! mkdir( $local_dir ) && ! is_dir( $local_dir ) ) {
throw new \RuntimeException( sprintf( 'Directory "%s" was not created', $local_dir ) );
}
}
}
}
/**
* Unzip helper function.
*
* @param $source
* @param $destination
*
* @return bool
*/
function unzip($source, $destination) {
$zip = new ZipArchive;
$res = $zip->open($source);
if ($res === TRUE) {
$zip->extractTo($destination);
$zip->close();
} else {
return false;
}
return true;
}
/**
* Print log.
*
* @param $string
*/
function prlog($string) {
echo date( 'Y-m-d H:i:s' ) . ' ' . $string . "\n";
}
define('TAB', "\t");
$directory['base'] = 'P:/FINFO_Import/';
$directory['nyabol'] = $directory['base'].'bolist_nya';
$directory['nyabol3'] = $directory['base'].'bolist_nya/vilma_3';
$directory['nyabol5'] = $directory['base'].'bolist_nya/vilma_5';
$directory['updbol'] = $directory['base'].'bolist_upd';
$directory['updbol3'] = $directory['base'].'bolist_upd/vilma_3';
$directory['updbol5'] = $directory['base'].'bolist_upd/vilma_5';
$directory['other'] = $directory['base'].'other';
prlog("\n\nStarting parser: ");
prlog( 'Setup start: ' );
setup_reciever_directories();
prlog( 'Setup complete: ' );
prlog( 'SFTP Start: ' );
if (! sync_sftp_directory() ) {
die('Kan inte synka FINFO!');
}
prlog( 'SFTP Complete: ' );
// echo parse_import_files_directory( base_path() . 'P:/FINFO_Import/' );
prlog( 'Parse Import Directory: ' );
$desc_files = parse_import_files_directory_descriptions( 'P:\FINFO_Import' );
prlog( 'Parse Import Complete: ' );
prlog( 'Listing Result and Performing Sorting: ' );
foreach ( $desc_files as $filename ) {
$parsed = parse_desc_file( $filename );
foreach ( $parsed as $zipfile ) {
echo $zipfile['levnr'].TAB.$zipfile['levname'].TAB.$zipfile['nya'].' nya artiklar'.PHP_EOL;
$filtyp = $zipfile['filtyp'];
$zipfil = $zipfile['zipfil'];
$zipfil_path_info = pathinfo( $zipfil );
$zipfil_namn = $zipfil_path_info['basename'];
$zipfil_ext = $zipfil_path_info['extension'];
$zipfil_num = mb_strcut( $zipfil_path_info['filename'],1);
switch ($filtyp) {
case 'BOL10':
case 'Bolist':
// Figure out what import filter to use;
$process = true;
// Do the uppacking etc.
if ( false !== stripos( $zipfile['ordertyp'], 'Manuell' ) || $zipfile['nya'] > 0 ) {
// Bolist with New articles.
$bo_destination_subdir = 'bolist_nya';
$bo_destination_unpack = 'I:/';
} else {
// Bolist with updated articles.
$bo_destination_subdir = 'bolist_upd';
$bo_destination_unpack = $directory['base'] . $bo_destination_subdir . '/';
}
$bo_source_zip_path = $zipfil;
$bo_source_zip_name = $zipfile['filename'];
$bo_destination = $directory['base'] . $bo_destination_subdir . '/'.$zipfil_namn;
$bo_vilma_identifier = $bo_destination_unpack . 'V' . $zipfil_num . '.TXT';
break;
default:
$process = false;
// Every other format than Bolist.
$bo_destination_subdir = 'other';
$bo_source_zip_path = $zipfil;
$bo_source_zip_name = $zipfile['filename'];
$bo_destination = $directory['base'] . $bo_destination_subdir . '/' . $zipfil_namn;
$bo_destination_unpack = $directory['base'] . $bo_destination_subdir . '/';
$bo_vilma_identifier = $bo_destination_unpack . 'F' . $zipfil_num . '.TXT';
}
// Parse and move everything where it needs to be
if(true || $process === true ) {
if ( $zipfil_ext === 'zip' && unzip( $bo_source_zip_path, $bo_destination_unpack ) ) {
//unlink( $zipfile['filename'] );
// Only do VILMA classification if it's an actual VILMA file.
if( $bo_destination_subdir !== 'other') {
$bo_vilma_typ = identify_vilma_filter( $bo_vilma_identifier );
echo "Vilma typ: " . $bo_vilma_typ . "\n\n";
} else {
echo "Vilma typ: EJ VILMA\n\n";
}
unlink( $bo_source_zip_path );
}
}
}
}
prlog( "\nParser complete: ");
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment