634 lines
22 KiB
PHP
634 lines
22 KiB
PHP
<?php
|
|
|
|
namespace App\Libraries\DigitMotor;
|
|
|
|
use App\Models\MotorMasterAddonAgeLimitModel;
|
|
use App\Models\MotorMasterDocTypeModel;
|
|
use App\Models\MotorMasterImportLogModel;
|
|
use App\Models\MotorMasterNcbModel;
|
|
use App\Models\MotorMasterNomineeRelationModel;
|
|
use App\Models\MotorMasterPincodeModel;
|
|
use App\Models\MotorMasterPreviousInsurerModel;
|
|
use App\Models\MotorMasterPreviousPolicyTypeModel;
|
|
use App\Models\MotorMasterProductModel;
|
|
use App\Models\MotorMasterRtoModel;
|
|
use App\Models\MotorMasterStateModel;
|
|
use App\Models\MotorMasterSubProductModel;
|
|
use App\Models\MotorMasterVehicleModel;
|
|
use App\Models\MotorMasterVoluntaryDeductibleModel;
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
|
|
|
|
/**
|
|
* Imports Digit kit Masters Excel files into motor_master_* tables.
|
|
*/
|
|
class DigitMasterImportService
|
|
{
|
|
protected string $mastersPath;
|
|
protected $db;
|
|
protected MotorMasterImportLogModel $logModel;
|
|
|
|
/** @var callable|null */
|
|
protected $progressCallback;
|
|
|
|
public function __construct(?string $mastersPath = null)
|
|
{
|
|
$this->mastersPath = rtrim($mastersPath ?: '', '/');
|
|
$this->db = db_connect();
|
|
$this->logModel = new MotorMasterImportLogModel();
|
|
}
|
|
|
|
public function setProgressCallback(?callable $cb): self
|
|
{
|
|
$this->progressCallback = $cb;
|
|
return $this;
|
|
}
|
|
|
|
public function createTables(string $sqlFile): void
|
|
{
|
|
if (!is_file($sqlFile)) {
|
|
throw new \RuntimeException('SQL file not found: ' . $sqlFile);
|
|
}
|
|
$sql = file_get_contents($sqlFile);
|
|
foreach (array_filter(array_map('trim', explode(';', $sql))) as $stmt) {
|
|
if ($stmt === '' || str_starts_with($stmt, '--')) {
|
|
continue;
|
|
}
|
|
// skip pure comment blocks
|
|
$clean = preg_replace('/^--.*$/m', '', $stmt);
|
|
$clean = trim($clean ?? '');
|
|
if ($clean === '') {
|
|
continue;
|
|
}
|
|
$this->db->query($clean);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array<string, array{rows:int,status:string,message?:string}>
|
|
*/
|
|
public function importAll(array $only = []): array
|
|
{
|
|
$map = [
|
|
'products' => fn () => $this->importProducts(),
|
|
'previous_insurers' => fn () => $this->importPreviousInsurers(),
|
|
'ncb' => fn () => $this->importNcb(),
|
|
'voluntary_deductible'=> fn () => $this->importVoluntaryDeductible(),
|
|
'previous_policy_type'=> fn () => $this->importPreviousPolicyType(),
|
|
'doc_types' => fn () => $this->importDocTypes(),
|
|
'nominee_relations' => fn () => $this->importNomineeRelations(),
|
|
'states' => fn () => $this->importStates(),
|
|
'sub_products' => fn () => $this->importSubProducts(),
|
|
'addon_age_limits' => fn () => $this->importAddonAgeLimits(),
|
|
'pincodes' => fn () => $this->importPincodes(),
|
|
'rtos' => fn () => $this->importRtos(),
|
|
'vehicles' => fn () => $this->importVehicles(),
|
|
];
|
|
|
|
if ($only) {
|
|
$map = array_intersect_key($map, array_flip($only));
|
|
}
|
|
|
|
$results = [];
|
|
foreach ($map as $key => $fn) {
|
|
$this->progress('Importing ' . $key . '...');
|
|
try {
|
|
$rows = $fn();
|
|
$results[$key] = ['rows' => $rows, 'status' => 'OK'];
|
|
$this->logImport($key, $rows, 'OK');
|
|
$this->progress($key . ': ' . $rows . ' rows');
|
|
} catch (\Throwable $e) {
|
|
$results[$key] = ['rows' => 0, 'status' => 'FAILED', 'message' => $e->getMessage()];
|
|
$this->logImport($key, 0, 'FAILED', $e->getMessage());
|
|
$this->progress($key . ' FAILED: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
protected function progress(string $message): void
|
|
{
|
|
if ($this->progressCallback) {
|
|
($this->progressCallback)($message);
|
|
}
|
|
}
|
|
|
|
protected function logImport(string $key, int $rows, string $status, ?string $message = null): void
|
|
{
|
|
try {
|
|
$this->logModel->insert([
|
|
'master_key' => $key,
|
|
'source_file' => $this->mastersPath,
|
|
'rows_upserted' => $rows,
|
|
'status' => $status,
|
|
'message' => $message,
|
|
'imported_at' => date('Y-m-d H:i:s'),
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
// ignore log failures
|
|
}
|
|
}
|
|
|
|
protected function findFile(array $candidates): string
|
|
{
|
|
foreach ($candidates as $name) {
|
|
$path = $this->mastersPath . '/' . $name;
|
|
if (is_file($path)) {
|
|
return $path;
|
|
}
|
|
}
|
|
throw new \RuntimeException('Master file not found. Tried: ' . implode(', ', $candidates));
|
|
}
|
|
|
|
protected function loadSheet(string $path, string $sheetName = null, int $maxRows = 0): array
|
|
{
|
|
$reader = IOFactory::createReaderForFile($path);
|
|
$reader->setReadDataOnly(true);
|
|
if (method_exists($reader, 'setReadEmptyCells')) {
|
|
$reader->setReadEmptyCells(false);
|
|
}
|
|
|
|
if ($sheetName) {
|
|
$reader->setLoadSheetsOnly([$sheetName]);
|
|
}
|
|
|
|
$spreadsheet = $reader->load($path);
|
|
$sheet = $sheetName
|
|
? $spreadsheet->getSheetByName($sheetName)
|
|
: $spreadsheet->getActiveSheet();
|
|
|
|
if (!$sheet) {
|
|
$sheet = $spreadsheet->getSheet(0);
|
|
}
|
|
|
|
$rows = $sheet->toArray(null, true, true, false);
|
|
$spreadsheet->disconnectWorksheets();
|
|
unset($spreadsheet);
|
|
|
|
if ($maxRows > 0 && count($rows) > $maxRows) {
|
|
$rows = array_slice($rows, 0, $maxRows);
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
protected function upsertBatch(string $table, array $rows, array $updateCols): int
|
|
{
|
|
if (!$rows) {
|
|
return 0;
|
|
}
|
|
|
|
$count = 0;
|
|
foreach (array_chunk($rows, 500) as $chunk) {
|
|
$this->db->table($table)->upsertBatch($chunk);
|
|
$count += count($chunk);
|
|
}
|
|
return $count;
|
|
}
|
|
|
|
protected function cell($row, int $idx): string
|
|
{
|
|
$v = $row[$idx] ?? '';
|
|
if ($v === null) {
|
|
return '';
|
|
}
|
|
return trim((string) $v);
|
|
}
|
|
|
|
public function importPreviousInsurers(): int
|
|
{
|
|
$path = $this->findFile(['Motor Prevoius insurer List.xlsx', 'Motor Previous insurer List.xlsx']);
|
|
$rows = $this->loadSheet($path);
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
if ($i === 0) {
|
|
continue;
|
|
}
|
|
$code = $this->cell($row, 0);
|
|
$name = $this->cell($row, 1);
|
|
if ($code === '' || !preg_match('/^\d+$/', $code) || $name === '' || strcasecmp($name, 'Name') === 0) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'insurer_code' => str_pad($code, 3, '0', STR_PAD_LEFT),
|
|
'insurer_name' => $name,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_previous_insurer', $out, ['insurer_name', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importProducts(): int
|
|
{
|
|
// Seed from known Digit product matrix (also present in Product Code Description workbook headers)
|
|
$now = date('Y-m-d H:i:s');
|
|
$products = [
|
|
['20201', '2W Comprehensive', '2W'],
|
|
['20202', '2W TP only', '2W'],
|
|
['20203', '2W SAOD', '2W'],
|
|
['20101', '4W Comprehensive', '4W'],
|
|
['20102', '4W TP only', '4W'],
|
|
['20103', '4W SAOD', '4W'],
|
|
['20301', 'CV Comprehensive', 'CV'],
|
|
['20302', 'CV TP only', 'CV'],
|
|
];
|
|
|
|
$out = [];
|
|
foreach ($products as [$code, $name, $class]) {
|
|
$out[] = [
|
|
'product_code' => $code,
|
|
'product_name' => $name,
|
|
'vehicle_class' => $class,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_product', $out, ['product_name', 'vehicle_class', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importNcb(): int
|
|
{
|
|
$path = $this->findFile(['NCB Master.xlsx']);
|
|
$rows = $this->loadSheet($path);
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
$order = 0;
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$code = strtoupper($this->cell($row, 0));
|
|
if ($code === '' || $code === 'NCB') {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'ncb_code' => $code,
|
|
'sort_order' => $order++,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_ncb', $out, ['sort_order', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importVoluntaryDeductible(): int
|
|
{
|
|
$path = $this->findFile(['Volunatry Deductible Master.xlsx', 'Voluntary Deductible Master.xlsx']);
|
|
$rows = $this->loadSheet($path);
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
$order = 0;
|
|
|
|
foreach ($rows as $row) {
|
|
$code = strtoupper($this->cell($row, 0));
|
|
if ($code === '' || str_contains($code, 'VOLUNTARY')) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'deductible_code' => $code,
|
|
'sort_order' => $order++,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_voluntary_deductible', $out, ['sort_order', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importPreviousPolicyType(): int
|
|
{
|
|
$path = $this->findFile(['Previous_Policy_Type.xlsx']);
|
|
$rows = $this->loadSheet($path, 'Description');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$code = strtoupper(trim($this->cell($row, 0)));
|
|
$desc = $this->cell($row, 1);
|
|
if ($i === 0 || $code === '' || $code === 'DOMNAME') {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'policy_type_code' => $code,
|
|
'description' => $desc,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_previous_policy_type', $out, ['description', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importDocTypes(): int
|
|
{
|
|
$path = $this->findFile(['Doc Type Master.xlsx', 'Doc Type Master1.xlsx']);
|
|
$rows = $this->loadSheet($path, 'KYC doc Type');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$code = strtoupper($this->cell($row, 0));
|
|
$type = strtoupper($this->cell($row, 1));
|
|
if ($i === 0 || $code === '' || $code === 'DOCUMENT_NUMBER') {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'doc_code' => $code,
|
|
'doc_type' => $type,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_doc_type', $out, ['doc_type', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importNomineeRelations(): int
|
|
{
|
|
$path = $this->findFile(['Nominee Master.xlsx']);
|
|
$rows = $this->loadSheet($path);
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $row) {
|
|
$code = strtoupper(trim($this->cell($row, 0)));
|
|
if ($code === '' || str_contains($code, 'NOMINEE')) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'relation_code' => $code,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_nominee_relation', $out, ['is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importStates(): int
|
|
{
|
|
$path = $this->findFile(['State Code Master (1).xlsx', 'State Code Master.xlsx']);
|
|
$rows = $this->loadSheet($path);
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$code = preg_replace('/\s+/', '', $this->cell($row, 0));
|
|
$name = trim($this->cell($row, 1));
|
|
if ($i === 0 || $code === '' || stripos($code, 'State') !== false) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'state_code' => $code,
|
|
'state_name' => $name,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_state', $out, ['state_name', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importSubProducts(): int
|
|
{
|
|
$path = $this->findFile(['Motor Product Code Description (1).xlsx', 'Motor Product Code Description.xlsx']);
|
|
$rows = $this->loadSheet($path, 'SubinsuranceProductcode');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
$businessType = 'NEW';
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$col0 = $this->cell($row, 0);
|
|
$label = $this->cell($row, 1);
|
|
$code = $this->cell($row, 2);
|
|
|
|
if ($col0 !== '') {
|
|
if (stripos($col0, 'rollover') !== false || stripos($col0, 'renewal') !== false) {
|
|
$businessType = 'ROLLOVER';
|
|
} elseif (stripos($col0, 'new') !== false) {
|
|
$businessType = 'NEW';
|
|
}
|
|
}
|
|
|
|
if ($label === '' || $code === '' || stripos($label, 'Product') === 0) {
|
|
continue;
|
|
}
|
|
|
|
// code cell may contain notes like "51 (51- 5 yr...)"
|
|
if (preg_match('/^([A-Za-z0-9]+)/', $code, $m)) {
|
|
$code = $m[1];
|
|
}
|
|
|
|
$out[] = [
|
|
'business_type' => $businessType,
|
|
'product_label' => $label,
|
|
'sub_product_code' => $code,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
// unique by business+label+code
|
|
$uniq = [];
|
|
foreach ($out as $row) {
|
|
$k = $row['business_type'] . '|' . $row['product_label'] . '|' . $row['sub_product_code'];
|
|
$uniq[$k] = $row;
|
|
}
|
|
|
|
if (!$uniq) {
|
|
return 0;
|
|
}
|
|
|
|
$this->db->table('motor_master_sub_product')->truncate();
|
|
$this->db->table('motor_master_sub_product')->insertBatch(array_values($uniq));
|
|
return count($uniq);
|
|
}
|
|
|
|
public function importAddonAgeLimits(): int
|
|
{
|
|
$path = $this->findFile(['Motor Product Code Description (1).xlsx', 'Motor Product Code Description.xlsx']);
|
|
$rows = $this->loadSheet($path, 'Addons age limit');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$name = $this->cell($row, 0);
|
|
if ($i === 0 || $name === '' || stripos($name, 'Add On') === 0) {
|
|
continue;
|
|
}
|
|
$out[] = [
|
|
'addon_name' => $name,
|
|
'age_limit_4w' => $this->cell($row, 1) ?: null,
|
|
'age_limit_2w' => $this->cell($row, 2) ?: null,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
if (!$out) {
|
|
return 0;
|
|
}
|
|
|
|
$this->db->table('motor_master_addon_age_limit')->truncate();
|
|
$this->db->table('motor_master_addon_age_limit')->insertBatch($out);
|
|
return count($out);
|
|
}
|
|
|
|
public function importPincodes(): int
|
|
{
|
|
$path = $this->findFile(['Pin Code and RTO Master_2023.xlsx']);
|
|
$rows = $this->loadSheet($path, 'PIN CODE');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
$seen = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$pin = preg_replace('/\D+/', '', $this->cell($row, 0));
|
|
if ($i === 0 || strlen($pin) !== 6 || isset($seen[$pin])) {
|
|
continue;
|
|
}
|
|
$seen[$pin] = true;
|
|
$out[] = [
|
|
'pincode' => $pin,
|
|
'city' => $this->cell($row, 1) ?: null,
|
|
'district' => $this->cell($row, 2) ?: null,
|
|
'street' => $this->cell($row, 3) ?: null,
|
|
'taluk' => $this->cell($row, 4) ?: null,
|
|
'segment' => $this->cell($row, 5) ?: null,
|
|
'state_code' => null,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_pincode', $out, [
|
|
'city', 'district', 'street', 'taluk', 'segment', 'is_active', 'imported_at',
|
|
]);
|
|
}
|
|
|
|
public function importRtos(): int
|
|
{
|
|
$path = $this->findFile(['Pin Code and RTO Master_2023.xlsx']);
|
|
$rows = $this->loadSheet($path, 'RTO MASTER');
|
|
$now = date('Y-m-d H:i:s');
|
|
$out = [];
|
|
$seen = [];
|
|
|
|
foreach ($rows as $i => $row) {
|
|
$city = $this->cell($row, 0);
|
|
$rto = strtoupper(preg_replace('/\s+/', '', $this->cell($row, 1)));
|
|
if ($i === 0 || $rto === '' || $rto === 'RTO' || isset($seen[$rto])) {
|
|
continue;
|
|
}
|
|
$seen[$rto] = true;
|
|
$out[] = [
|
|
'rto_code' => $rto,
|
|
'city_state' => $city ?: null,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
}
|
|
|
|
return $this->upsertBatch('motor_master_rto', $out, ['city_state', 'is_active', 'imported_at']);
|
|
}
|
|
|
|
public function importVehicles(): int
|
|
{
|
|
$path = $this->findFile(['Vehicle Master_New (2).xlsx', 'Vehicle Master_New.xlsx', 'Vehicle Master.xlsx']);
|
|
$this->progress('Loading vehicle master workbook (large file)...');
|
|
|
|
$reader = IOFactory::createReaderForFile($path);
|
|
$reader->setReadDataOnly(true);
|
|
if (method_exists($reader, 'setReadEmptyCells')) {
|
|
$reader->setReadEmptyCells(false);
|
|
}
|
|
|
|
$spreadsheet = $reader->load($path);
|
|
$sheet = $spreadsheet->getSheet(0);
|
|
$highestRow = (int) $sheet->getHighestDataRow();
|
|
$this->progress('Vehicle master rows to scan: ' . $highestRow);
|
|
|
|
$now = date('Y-m-d H:i:s');
|
|
$batch = [];
|
|
$count = 0;
|
|
$chunkSize = 500;
|
|
|
|
for ($r = 2; $r <= $highestRow; $r++) {
|
|
$code = trim((string) $sheet->getCell('A' . $r)->getValue());
|
|
if ($code === '') {
|
|
continue;
|
|
}
|
|
|
|
$batch[] = [
|
|
'vehicle_code' => $code,
|
|
'make' => trim((string) $sheet->getCell('B' . $r)->getValue()),
|
|
'model' => trim((string) $sheet->getCell('C' . $r)->getValue()),
|
|
'variant' => trim((string) $sheet->getCell('D' . $r)->getValue()) ?: null,
|
|
'body_type' => trim((string) $sheet->getCell('E' . $r)->getValue()) ?: null,
|
|
'seating_capacity' => $this->toInt($sheet->getCell('F' . $r)->getValue()),
|
|
'power' => $this->toFloat($sheet->getCell('G' . $r)->getValue()),
|
|
'cubic_capacity' => $this->toFloat($sheet->getCell('H' . $r)->getValue()),
|
|
'gross_vehicle_weight' => $this->toFloat($sheet->getCell('I' . $r)->getValue()),
|
|
'fuel_type' => trim((string) $sheet->getCell('J' . $r)->getValue()) ?: null,
|
|
'no_of_wheels' => $this->toInt($sheet->getCell('K' . $r)->getValue()),
|
|
'abs' => substr(trim((string) $sheet->getCell('L' . $r)->getValue()), 0, 1) ?: null,
|
|
'air_bags' => $this->toInt($sheet->getCell('M' . $r)->getValue()),
|
|
'length_m' => $this->toFloat($sheet->getCell('N' . $r)->getValue()),
|
|
'ex_showroom_price' => $this->toFloat($sheet->getCell('O' . $r)->getValue()),
|
|
'price_year' => $this->toInt($sheet->getCell('P' . $r)->getValue()),
|
|
'production_status' => trim((string) $sheet->getCell('Q' . $r)->getValue()) ?: null,
|
|
'manufacturing' => trim((string) $sheet->getCell('R' . $r)->getValue()) ?: null,
|
|
'vehicle_type' => trim((string) $sheet->getCell('S' . $r)->getValue()) ?: null,
|
|
'is_active' => 1,
|
|
'imported_at' => $now,
|
|
];
|
|
|
|
if (count($batch) >= $chunkSize) {
|
|
$this->db->table('motor_master_vehicle')->upsertBatch($batch);
|
|
$count += count($batch);
|
|
$batch = [];
|
|
if ($count % 5000 === 0) {
|
|
$this->progress('Vehicles upserted: ' . $count);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($batch) {
|
|
$this->db->table('motor_master_vehicle')->upsertBatch($batch);
|
|
$count += count($batch);
|
|
}
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
unset($spreadsheet);
|
|
|
|
return $count;
|
|
}
|
|
|
|
protected function toInt($v): ?int
|
|
{
|
|
if ($v === null || $v === '') {
|
|
return null;
|
|
}
|
|
if (!is_numeric($v)) {
|
|
return null;
|
|
}
|
|
return (int) $v;
|
|
}
|
|
|
|
protected function toFloat($v): ?float
|
|
{
|
|
if ($v === null || $v === '') {
|
|
return null;
|
|
}
|
|
if (!is_numeric($v)) {
|
|
return null;
|
|
}
|
|
return (float) $v;
|
|
}
|
|
}
|