XML PARSER FLUX V2

This commit is contained in:
Jérémy Munsch 2021-04-08 09:25:28 +02:00
parent ef50ebcefb
commit 8219e60947
18 changed files with 642 additions and 406 deletions

17
app/Enums/LogType.php Normal file
View file

@ -0,0 +1,17 @@
<?php
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self debug()
* @method static self log()
* @method static self warning()
* @method static self info()
* @method static self error()
* @method static self critical()
*/
final class LogType extends BaseEnum
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace App\Exceptions;
use Exception;
class AbortXmlImportException extends Exception
{
}

View file

@ -3,9 +3,9 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Breeders; use App\Models\Breeders;
use App\Models\BreedersDatas; use App\Models\XmlBreeder;
use App\Models\Traceability; use App\Models\Traceability;
use App\Models\TraceabilityDatas; use App\Models\XmlTraceability;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class TraceabilityController extends Controller class TraceabilityController extends Controller
@ -13,7 +13,7 @@ class TraceabilityController extends Controller
public function search(Request $request) public function search(Request $request)
{ {
$searchCode = filter_var($request->code, FILTER_SANITIZE_NUMBER_INT); $searchCode = filter_var($request->code, FILTER_SANITIZE_NUMBER_INT);
$tracaDatas = TraceabilityDatas::where('no_lot', 'LIKE', $searchCode)->first(); $tracaDatas = XmlTraceability::where('lot_code', 'LIKE', $searchCode)->first();
$log = new Traceability(); $log = new Traceability();
$log->code = $searchCode; $log->code = $searchCode;
@ -23,7 +23,7 @@ class TraceabilityController extends Controller
$log->save(); $log->save();
return json_encode(['status' => 'KO', 'code' => 100]); return json_encode(['status' => 'KO', 'code' => 100]);
} else { } else {
if ($tracaDatas->code_traca_prod_elab === 1) { if ($tracaDatas->code_traca_prod_elab) {
// Produit élaboré // Produit élaboré
$log->response_type = 3; $log->response_type = 3;
$log->save(); $log->save();
@ -32,11 +32,13 @@ class TraceabilityController extends Controller
// Si éleveur trouvé, alors c'est un éleveur OCB publié // Si éleveur trouvé, alors c'est un éleveur OCB publié
$breeder = Breeders::where([ $breeder = Breeders::where([
['status', 1], ['breeder_code', 'LIKE', '%' . $tracaDatas->no_opa . $tracaDatas->no_elev] ['status', 1], [
'breeder_code', 'LIKE', '%' . $tracaDatas->opa_code . $tracaDatas->inuav_code
]
])->first(); ])->first();
if (!$breeder) { if (!$breeder) {
// Sinon, c'est un éleveur non OCB // Sinon, c'est un éleveur non OCB
$breeder = BreedersDatas::where('code_eleveur', $tracaDatas->no_elev)->first(); $breeder = XmlBreeder::where('code_eleveur', $tracaDatas->inuav_code)->first();
if (!$breeder) { if (!$breeder) {
// Eleveur non trouvé // Eleveur non trouvé
$log->response_type = 4; $log->response_type = 4;

View file

@ -2,134 +2,37 @@
namespace App\Jobs; namespace App\Jobs;
use App\Models\BreedersDatas; use App\Models\XmlBreeder;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use SimpleXMLElement;
class XmlEleveursReader implements ShouldQueue class XmlEleveursReader extends XmlJobs
{ {
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public $console = null; protected $disk = 'eleveurs';
protected $takeColumns = [
'codeopa.Nom' => 'opa_nom',
'codeopa.code' => 'opa_code',
'NomEleveur' => 'nom',
'CodeEleveur' => 'inuav_code',
'Prenom' => 'prenom',
'code' => 'unique_key',
'codePostal' => 'postal',
'Ville' => 'city',
'LongitudeGps' => 'longitude',
'LatitudeGps' => 'latitude'
];
protected $nullableFields = ['longitude', 'latitude'];
protected $uniqueKeyField = ['unique_key', 'inuav_code'];
/**
* TODO: Job clean very old XML PARSED DATA
*
* @return void
*/
public function handle() public function handle()
{ {
$this->log(__CLASS__ . ' Démarrage du traitement'); $this->parseData('ELEVEURS', XmlBreeder::class);
$files = Storage::disk('eleveur')->files();
// Suppression des fichiers dans archives qui ont plus de 2j
$archives = Storage::disk('eleveur')->files('archives');
foreach ($archives as $archive) {
if ($archive == ".gitignore" || $archive == ".gitkeep") {
continue;
}
if (Storage::disk('eleveur')->lastModified($archive) < strtotime(Carbon::now()->subDays(2))) {
Storage::disk('eleveur')->delete($archive);
}
}
$progress = 0;
$total = count($files) - 1;
foreach ($files as $filename) {
if ($filename == ".gitignore" || $filename == ".gitkeep") {
continue;
}
// ---- Récupération du contenu
$file = Storage::disk('eleveur')->get($filename);
$fileContent = simplexml_load_string($file, null, LIBXML_NOCDATA);
// Transforme le fichier en tableau de données
$eleveurs = $this->extract($fileContent);
// Mise en BDD des données du fichier xml
$fields = [];
foreach ($eleveurs['ELEVEURS'] as $eleveur) {
$fields[] = $this->processFields($eleveur);
}
// Mise en base des données
foreach ($fields as $field) {
$checkFields = ['code' => $field["code"], 'code_eleveur' => $field['code_eleveur']];
BreedersDatas::updateOrCreate($checkFields, $field);
}
Storage::disk('eleveur')->move($filename, 'archives/' . $filename);
$this->log(__CLASS__ . sprintf(' traitement %d sur %s ', $progress++, $total));
}
$this->log(__CLASS__ . ' Fin du traitement');
}
private function log(string $message)
{
if ($this->console) {
$this->console->info($message);
}
Log::debug($message);
}
private function extract($sxe = null)
{
if (!$sxe instanceof SimpleXMLElement) {
return array();
}
$extract = array();
foreach ($sxe->children() as $key => $value) {
if (array_key_exists($key, $extract)) {
if (!isset($extract[$key][0])) {
$tmp_extract = $extract[$key];
$extract[$key] = array();
$extract[$key][0] = $tmp_extract;
} else {
$extract[$key] = (array)$extract[$key];
}
}
if ($value->count()) {
if (isset($extract[$key]) && is_array($extract[$key])) {
$extract[$key][] = $this->extract($value);
} else {
$extract[$key] = $this->extract($value);
}
} else {
if (isset($extract[$key]) && is_array($extract[$key])) {
$extract[$key][] = empty(strval($value)) ? null : strval($value);
} else {
$extract[$key] = empty(strval($value)) ? null : strval($value);
}
}
}
return $extract;
}
private function processFields($fields)
{
$result = [];
foreach ($fields as $key => $field) {
// Gestion des balises CodeOpa et OPA
if (is_array($field)) {
if (isset($field['OPA'])) {
$result['code_opa'] = $field['OPA']['code'];
$result['nom'] = $field['OPA']['Nom'];
}
} else {
// Le ctype_upper est la pour les balise entièrement en majuscule
$result[Str::snake(ctype_upper($key) ? strtolower($key) : $key)] = $field;
}
}
return $result;
} }
} }

430
app/Jobs/XmlJobs.php Normal file
View file

@ -0,0 +1,430 @@
<?php
namespace App\Jobs;
use App\Enums\LogType;
use App\Exceptions\AbortXmlImportException;
use ErrorException;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RecursiveArrayIterator;
use RecursiveIteratorIterator;
use SimpleXMLElement;
use TypeError;
abstract class XmlJobs implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/**
* The Laravel disk name
*
* @var string
*/
protected $disk = null;
/**
* The columns to take from the XML
* subcolumns can be added with a dot
*
* @var array
*/
protected $takeColumns = [];
/**
* The columns allowed to be null
*
* @var array
*/
protected $nullableFields = [];
/**
* This is for Laravel Console usage
*/
public $console = null;
/**
* The relative folder where to archive data
*
* @var string
*/
private $archiveFolderName = 'archives';
/**
* The files extension to consider
*
* @var string
*/
private $wantedFileExt = 'xml';
/**
* Need to encapsulate the freeking XML
* Because provided one is dirty
*
* @var boolean
*/
protected $encapsulate = false;
/**
* The files to ignore
*
* @var array
*/
private $ignoreFiles = [
'.gitignore', '.gitkeep'
];
/**
* Parse Data from the XML and gives it to the callback
*
* @param string $entityName
* @param string $modelClass
* @return void
*/
protected function parseData(string $entityName, string $modelClass): void
{
/** @var Filesystem */
$disk = $this->getDisk();
$this->log('Démarrage du traitement');
$files = $disk->files();
$progress = 1;
$total = count(array_filter($files, function ($filename) {
if ($this->fileHasToBeIgnored($filename)) {
return false;
}
return true;
}));
foreach ($files as $filename) {
if ($this->fileHasToBeIgnored($filename)) {
continue;
}
$this->log(sprintf(' traitement %d sur %s ', $progress++, $total));
/** @var string $data */
$data = $disk->get($filename);
if ($this->encapsulate) {
$data = sprintf('<Root>%s</Root>', $data);
/** @var SimpleXMLElement|false */
$xmlContent = simplexml_load_string($data);
} else {
/** @var SimpleXMLElement|false */
$xmlContent = simplexml_load_string($data, null, LIBXML_NOCDATA);
}
if ($xmlContent === false) {
$this->log(
sprintf('File %s could not be parsed (simplexml_load_string)', $filename),
LogType::critical()
);
continue; // ignore the file
}
$data = $this->extract($xmlContent);
try {
$lines = [];
foreach ($data[$entityName] as $traca) {
$lines[] = $this->processFields($traca);
}
// Mise en base des données
foreach ($lines as $line) {
/** @var array Unique Key columns */
$uniqueColumnsKey = [];
foreach ($this->uniqueKeyField as $uField) {
$uniqueColumnsKey[$uField] = $line[$uField];
}
forward_static_call_array(
[$modelClass, 'updateOrCreate'],
[$uniqueColumnsKey, $line]
);
}
} catch (ErrorException | TypeError $e) {
$this->log(
sprintf(
'File %s could not be parsed => %s on line %d',
$filename,
$e->getMessage(),
$e->getLine()
),
LogType::critical()
);
continue; // ignore the file
} catch (AbortXmlImportException $e) {
$this->log(
sprintf(
'File %s could not be parsed => %s on line %d',
$filename,
$e->getMessage(),
$e->getLine()
),
LogType::error()
);
continue; // ignore the file
}
$this->moveToArchives($filename);
}
}
/**
* Recursive extract to array
*
* @param \SimpleXMLElement|false $sxe
* @return array
*/
protected function extract($sxe = null): array
{
if (!$sxe instanceof SimpleXMLElement) {
return array();
}
$extract = array();
foreach ($sxe->children() as $key => $value) {
if ($value->count()) {
$extract[$key][] = $this->extract($value);
continue;
}
$value = strval($value);
if (array_key_exists($key, $extract) and is_array($extract[$key])) {
$extract[$key][] = strlen($value) ? $value : null;
} else {
$extract[$key] = strlen($value) ? $value : null;
}
}
return $extract;
}
/**
* Process fields to gather data
*
* @param array $fields
* @return array
* @throws AbortXmlImportException
*/
protected function processFields(array $fields): array
{
$result = [];
foreach ($fields as $key => $field) {
if (!($key = $this->shouldFieldBeConsidered($key))) {
continue;
}
if (!$this->isFieldNullable($key) && is_null($field)) {
throw new AbortXmlImportException(sprintf('The field %s is not allowed to be null', $key));
}
if (is_array($field)) {
// Flatten data
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($field));
foreach ($it as $k => $f) {
$ko = sprintf('%s.%s', $key, $k);
if (!$this->isFieldNullable($ko) && is_null($f)) {
throw new AbortXmlImportException(sprintf('%s : The field %s is not allowed to be null', get_class($this), $ko));
}
if (!($k = $this->shouldFieldBeConsidered($ko))) {
continue;
}
$result[$k] = $f;
}
} else {
$result[$key] = $field;
}
}
return $result;
}
/**
* Is the filed nullable
*
* @param string $key
* @return boolean
*/
private function isFieldNullable(string $key): bool
{
if (in_array($key, $this->nullableFields)) {
return true;
}
return false;
}
/**
* - replace key name with the corresponding alias
* - strtolower the key
* - snake_case the key
*
* @param string $key
* @return string|false
*/
private function shouldFieldBeConsidered(string $key)
{
$key = strtolower($key);
foreach ($this->takeColumns as $k => $alias) {
if (strtolower($k) === $key) {
return Str::snake(strtolower($alias));
}
}
return false;
}
/**
* Is the file to be ignored
*
* @param string $filename
* @return boolean
*/
protected function fileHasToBeIgnored(string $filename): bool
{
return in_array($filename, $this->ignoreFiles) or !$this->isFileXml($filename);
}
/**
* Check if the file is an xml file
*
* @param string $filename
* @return boolean
*/
protected function isFileXml(string $filename): bool
{
$isXml = strtolower(pathinfo($filename, \PATHINFO_EXTENSION)) === 'xml';
if (!$isXml) {
Log::warning(sprintf('%s : unwanted file type in %s', get_class($this), $filename));
}
return $isXml;
}
/**
* Move the file to archives
*
* @param string $filename
* @return void
*/
protected function moveToArchives(string $filename): void
{
if (!$this->getDisk()->move($filename, sprintf('%s/%s', $this->archiveFolderName, $filename))) {
$this->log(
sprintf(
'File %s could not be moved to archives',
$filename
),
LogType::warning()
);
}
}
/**
* Suppression des fichiers dans
* archives qui ont plus de 2j
*
* @return void
*/
private function clearOldArchives(): void
{
$disk = $this->getDisk();
$archives = $disk->files($this->archiveFolderName);
// /** @var File */
foreach ($archives as $archive) {
if (in_array($archive, $this->ignoreFiles)) {
continue;
}
if ($disk->lastModified($archive) < strtotime(Carbon::now()->subDays(2))) {
if (!$disk->delete($archive)) {
Log::critical(sprintf('%s : Could not delete file %s', get_class($this), $archive));
};
}
}
}
/**
* Get the concerned disk
*
* @return Filesystem
*/
protected function getDisk(): Filesystem
{
return Storage::disk($this->disk);
}
/**
* Logs data
*
* @param string $message
* @param LogType $logtype
* @return void
*/
protected function log(string $message, LogType $logtype = null): void
{
if (!$logtype) {
$logtype = LogType::debug();
}
$message = sprintf('%s : %s', get_class($this), $message);
switch ($logtype->value) {
case LogType::debug()->value:
Log::debug($message);
break;
case LogType::info()->value:
Log::info($message);
break;
case LogType::log()->value:
Log::log($message);
break;
case LogType::warning()->value:
Log::warning($message);
break;
case LogType::error()->value:
Log::error($message);
break;
case LogType::critical()->value:
Log::critical($message);
break;
default:
throw new Exception(sprintf('%s : unhandled log type %s', get_class($this), $logtype->label));
}
$this->consolePrint($message, $logtype);
}
/**
* Prints to the console
*
* @param string $message
* @param LogType $logtype
* @return void
*/
protected function consolePrint(string $message, LogType $logtype): void
{
if ($this->console) {
switch ($logtype->value) {
case LogType::debug()->value:
case LogType::info()->value:
case LogType::log()->value:
$this->console->info($message);
break;
case LogType::warning()->value:
$this->console->comment($message);
break;
case LogType::error()->value:
case LogType::critical()->value:
$this->console->error($message);
break;
default:
throw new Exception(sprintf('%s : unhandled log type %s', get_class($this), $logtype->label));
}
}
}
}

View file

@ -2,135 +2,38 @@
namespace App\Jobs; namespace App\Jobs;
use App\Models\TraceabilityDatas; use App\Models\XmlTraceability;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use SimpleXMLElement;
class XmlTracaReader implements ShouldQueue class XmlTracaReader extends XmlJobs
{ {
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public $console = null; protected $disk = 'tracabilite';
protected $takeColumns = [
'NO_LOT' => 'lot_code',
'NO_OPA' => 'opa_code',
'NO_ELEV' => 'inuav_code',
'LOTABA' => 'abatage_code',
'DATABA' => 'abatage_date',
'CODE_TRACA_PROD_ELAB' => 'produit_elab'
];
protected $encapsulate = true;
protected $nullableFields = [
'opa_code', 'inuav_code',
'abatage_code', 'abatage_date'
];
protected $uniqueKeyField = ['lot_code'];
/** /**
* Execute the job. * TODO: Job clean very old XML PARSED DATA
* *
* @return void * @return void
*/ */
public function handle() public function handle()
{ {
$this->log(__CLASS__ . ' Démarrage du traitement'); $this->parseData('ENRLOT', XmlTraceability::class);
$files = Storage::disk('tracabilite')->files();
// Suppression des fichiers dans archives qui ont plus de 2j
$archives = Storage::disk('tracabilite')->files('archives');
foreach ($archives as $archive) {
if ($archive == ".gitignore" || $archive == ".gitkeep") {
continue;
}
if (Storage::disk('tracabilite')->lastModified($archive) < strtotime(Carbon::now()->subDays(2))) {
Storage::disk('tracabilite')->delete($archive);
}
}
$progress = 0;
$total = count($files) - 1;
foreach ($files as $filename) {
if ($filename == ".gitignore" || $filename == ".gitkeep") {
continue;
}
// ---- Récupération du contenu
$file = Storage::disk('tracabilite')->get($filename);
$fileContent = simplexml_load_string('<Root>' . $file . '</Root>');
// Transforme le fichier en tableau de données
$tracas = $this->extract($fileContent);
// Mise en BDD des données du fichier xml
$fields = [];
foreach ($tracas['ENRLOT'] as $traca) {
$fields[] = $this->processFields($traca);
}
// Mise en base des données
foreach ($fields as $field) {
$checkFields = [
'no_lot' => $field["no_lot"],
'no_opa' => $field['no_opa'],
'no_elev' => $field['no_elev']
];
TraceabilityDatas::updateOrCreate($checkFields, $field);
}
Storage::disk('tracabilite')->move($filename, 'archives/' . $filename);
$this->log(__CLASS__ . sprintf(' traitement %d sur %s ', $progress++, $total));
}
$this->log(__CLASS__ . ' Fin du traitement');
}
private function log(string $message)
{
if ($this->console) {
$this->console->info($message);
}
Log::debug($message);
}
private function extract($sxe = null)
{
if (!$sxe instanceof SimpleXMLElement) {
return array();
}
$extract = array();
foreach ($sxe->children() as $key => $value) {
if (array_key_exists($key, $extract)) {
if (!isset($extract[$key][0])) {
$tmp_extract = $extract[$key];
$extract[$key] = array();
$extract[$key][0] = $tmp_extract;
} else {
$extract[$key] = (array)$extract[$key];
}
}
if ($value->count()) {
if (isset($extract[$key]) && is_array($extract[$key])) {
$extract[$key][] = $this->extract($value);
} else {
$extract[$key] = $this->extract($value);
}
} else {
if (isset($extract[$key]) && is_array($extract[$key])) {
$extract[$key][] = empty(strval($value)) && strval($value) !== '0' ? null : strval($value);
} else {
$extract[$key] = empty(strval($value)) && strval($value) !== '0' ? null : strval($value);
}
}
}
return $extract;
}
private function processFields($fields)
{
$result = [];
foreach ($fields as $key => $field) {
// Le ctype_upper est la pour les balise entièrement en majuscule
$result[strtolower($key)] = $field;
}
return $result;
} }
} }

View file

@ -1,33 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BreedersDatas extends Model
{
protected $fillable = [
"typemouvementinformatique",
"code",
"nom_eleveur",
"code_opa",
"nom",
"telephone",
"code_eleveur",
"code_activite",
"bague",
"gsm",
"fax",
"prenom",
"adresse",
"adresse_compl",
"etat_code",
"code_postal",
"ville",
"email",
"libelle",
"longitude_gps",
"latitude_gps",
];
}

View file

@ -1,20 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TraceabilityDatas extends Model
{
protected $fillable = [
'no_lot',
'no_opa',
'no_elev',
'lotaba',
'databa',
'num_sb',
'site_abat',
'code_traca_prod_elab',
];
}

20
app/Models/XmlBreeder.php Normal file
View file

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class XmlBreeder extends Model
{
protected $fillable = [
"unique_key",
"inuav_code",
"nom",
"prenom",
"postal",
"city",
"longitude",
"latitude"
];
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class XmlTraceability extends Model
{
protected $table = 'xml_tracability';
protected $fillable = [
'lot_code',
'opa_code',
'inuav_code',
'abatage_code',
'abatage_date',
'produit_elab'
];
}

View file

@ -70,9 +70,9 @@ return [
'root' => storage_path('inco'), 'root' => storage_path('inco'),
], ],
'eleveur' => [ 'eleveurs' => [
'driver' => 'local', 'driver' => 'local',
'root' => storage_path('eleveur'), 'root' => storage_path('eleveurs'),
], ],
'tracabilite' => [ 'tracabilite' => [

View file

@ -1,57 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
class CreateBreedersDatasTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('breeders_datas', function (Blueprint $table) {
$table->id();
$table->string('typemouvementinformatique')->nullable();
$table->string('code')->nullable();
$table->string('nom_eleveur')->nullable();
$table->string('code_opa')->nullable();
$table->string('nom')->nullable();
$table->string('telephone')->nullable();
$table->string('code_eleveur')->nullable();
$table->string('code_activite')->nullable();
$table->string('bague')->nullable();
$table->string('gsm')->nullable();
$table->string('fax')->nullable();
$table->string('prenom')->nullable();
$table->string('adresse')->nullable();
$table->string('adresse_compl')->nullable();
$table->string('etat_code')->nullable();
$table->string('code_postal')->nullable();
$table->string('ville')->nullable();
$table->string('email')->nullable();
$table->string('libelle')->nullable();
$table->string('longitude_gps')->nullable();
$table->string('latitude_gps')->nullable();
$table->timestamps();
$table->index('code_eleveur');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('breeders_datas');
}
}

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
class CreateXmlBreedersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('xml_breeders', function (Blueprint $table) {
$table->id();
$table->string('unique_key');
$table->string('inuav_code');
$table->string('nom');
$table->string('prenom');
$table->string('postal');
$table->string('city');
$table->string('longitude')->nullable();
$table->string('latitude')->nullable();
$table->timestamps();
$table->unique(['unique_key', 'inuav_code']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('breeders_datas');
}
}

View file

@ -1,45 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
class CreateTracabilityDataTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tracability_data', function (Blueprint $table) {
$table->id();
$table->string('no_lot')->nullable();
$table->string('no_elev')->nullable();
$table->string('databa')->nullable();
$table->boolean('code_traca_prod_elab')->default(false);
$table->integer('no_opa')->unsigned()->default(0);
$table->integer('site_abat')->unsigned()->default(0);
$table->bigInteger('lotaba')->nullable()->default(0);
$table->bigInteger('num_sb')->nullable()->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tracability_data');
}
}

View file

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
class CreateXmlTracabilityTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('xml_tracability', function (Blueprint $table) {
$table->id();
$table->string('lot_code')->unique();
$table->string('opa_code')->nullable();
$table->string('inuav_code')->nullable();
$table->boolean('produit_elab');
$table->bigInteger('abatage_code')->nullable();
$table->date('abatage_date')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tracability_data');
}
}

1
public/storage Symbolic link
View file

@ -0,0 +1 @@
/mnt/c/www/legaulois2020/storage/app/public

2
storage/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
eleveurs/*
tracabilite/*