Skip to content

Commit

Permalink
feat: autodetect data type during import
Browse files Browse the repository at this point in the history
  • Loading branch information
luka-nextcloud committed Feb 22, 2024
1 parent c3db289 commit a93b81b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 12 deletions.
25 changes: 23 additions & 2 deletions lib/Service/ColumnService.php
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,29 @@ public function findOrCreateColumnsByTitleForTableAsArray(?int $tableId, ?int $v
// if column was not found
if($result[$i] === '' && $createUnknownColumns) {
$description = $this->l->t('This column was automatically created by the import service.');
$subType = $dataTypes[$i] === 'text' ? 'line' : '';
$result[$i] = $this->create($userId, $tableId, $viewId, $dataTypes[$i], $subType, $title, false, $description, null, null, null, null, null, null, null, null, null, null, null, null, []);
$result[$i] = $this->create(
$userId,
$tableId,
$viewId,
$dataTypes[$i]['type'],
$dataTypes[$i]['subtype'] ?? '',
$title,
false,
$description,
null,
null,
null,
$dataTypes[$i]['number_prefix'] ?? null,
$dataTypes[$i]['number_suffix'] ?? null,
null,
null,
null,
$dataTypes[$i]['number_decimals'] ?? null,
null,
$dataTypes[$i]['selection_default'] ?? null,
null,
[]
);
$countCreatedColumns++;
}
}
Expand Down
87 changes: 77 additions & 10 deletions lib/Service/ImportService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use OCP\Files\NotPermittedException;
use OCP\IUserManager;
use OCP\Server;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Worksheet\Row;
Expand Down Expand Up @@ -201,10 +203,13 @@ private function createRow(Row $row): void {
continue;
}

/** @var Column $column */
$column = $this->columns[$i];

// if cell is empty
if(!$cell || $cell->getValue() === null) {
$this->logger->info('Cell is empty while fetching rows data for importing.');
if($this->columns[$i]->getMandatory()) {
if($column->getMandatory()) {
$this->logger->warning('Mandatory column was not set');
$this->countErrors++;
return;
Expand All @@ -213,8 +218,12 @@ private function createRow(Row $row): void {
}

$value = $cell->getValue();
if ($this->columns[$i]->getType() === 'datetime') {
if ($column->getType() === 'datetime') {
$value = Date::excelToDateTimeObject($value)->format('Y-m-d H:i');
} elseif ($column->getType() === 'number' && $column->getNumberSuffix() === '%') {
$value = $value * 100;
} elseif ($column->getType() === 'selection' && $column->getSubtype() === 'check') {
$value = $cell->getFormattedValue() === 'TRUE' ? 'true' : 'false';
}

$data[] = [
Expand Down Expand Up @@ -255,16 +264,9 @@ private function getColumns(Row $firstRow, Row $secondRow): void {
foreach ($cellIterator as $cell) {
if ($cell && $cell->getValue() !== null && $cell->getValue() !== '') {
$titles[] = $cell->getValue();
$originDataType = $secondRowCellIterator->current()->getDataType();

// Convert data type to our data type
if (Date::isDateTime($secondRowCellIterator->current()) || $originDataType === 'd') {
$dataTypes[] = 'datetime';
} elseif ($originDataType === 'n') {
$dataTypes[] = 'number';
} else {
$dataTypes[] = 'text';
}
$dataTypes[] = $this->parseColumnDataType($secondRowCellIterator->current());
} else {
$this->logger->debug('No cell given or cellValue is empty while loading columns for importing');
$this->countErrors++;
Expand All @@ -278,4 +280,69 @@ private function getColumns(Row $firstRow, Row $secondRow): void {
}
}

private function parseColumnDataType(Cell $cell): array {
$originDataType = $cell->getDataType();
$value = $cell->getValue();
$formattedValue = $cell->getFormattedValue();
$dataType = [
'type' => 'text',
'subtype' => 'line',
];

if (Date::isDateTime($cell) || $originDataType === DataType::TYPE_ISO_DATE) {
$dataType = [
'type' => 'datetime',
];
} elseif ($originDataType === DataType::TYPE_NUMERIC) {
if (str_contains($formattedValue, '%')) {
$dataType = [
'type' => 'number',
'number_decimals' => 2,
'number_suffix' => '%',
];
} elseif (str_contains($formattedValue, '')) {
$dataType = [
'type' => 'number',
'number_decimals' => 2,
'number_suffix' => '',
];
} elseif (str_contains($formattedValue, 'EUR')) {
$dataType = [
'type' => 'number',
'number_decimals' => 2,
'number_suffix' => 'EUR',
];
} elseif (str_contains($formattedValue, '$')) {
$dataType = [
'type' => 'number',
'number_decimals' => 2,
'number_prefix' => '$',
];
} elseif (str_contains($formattedValue, 'USD')) {
$dataType = [
'type' => 'number',
'number_decimals' => 2,
'number_suffix' => 'USD',
];
} elseif (is_float($value)) {
$decimals = strlen(substr(strrchr($value, "."), 1));

Check failure on line 328 in lib/Service/ImportService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable28

InvalidScalarArgument

lib/Service/ImportService.php:328:39: InvalidScalarArgument: Argument 1 of strrchr expects string, but float provided (see https://psalm.dev/012)

Check failure on line 328 in lib/Service/ImportService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidScalarArgument

lib/Service/ImportService.php:328:39: InvalidScalarArgument: Argument 1 of strrchr expects string, but float provided (see https://psalm.dev/012)
$dataType = [
'type' => 'number',
'number_decimals' => $decimals,
];
} else {
$dataType = [
'type' => 'number',
];
}
} elseif ($originDataType === DataType::TYPE_BOOL) {
$dataType = [
'type' => 'selection',
'subtype' => 'check',
'selection_default' => 'false',
];
}

return $dataType;
}
}

0 comments on commit a93b81b

Please sign in to comment.