Merge remote-tracking branch 'origin/develop'

This commit is contained in:
snipe
2025-10-01 11:19:35 +01:00
9 changed files with 76 additions and 17 deletions

View File

@@ -363,7 +363,7 @@ class AssetsController extends Controller
$asset->purchase_cost = $request->input('purchase_cost', null);
$asset->purchase_date = $request->input('purchase_date', null);
$asset->next_audit_date = $request->input('next_audit_date', null);
if ($request->filled('purchase_date') && !$request->filled('asset_eol_date') && ($asset->model->eol > 0)) {
if ($request->filled('purchase_date') && !$request->filled('asset_eol_date') && ($asset->model?->eol > 0)) {
$asset->purchase_date = $request->input('purchase_date', null);
$asset->asset_eol_date = Carbon::parse($request->input('purchase_date'))->addMonths($asset->model->eol)->format('Y-m-d');
$asset->eol_explicit = false;
@@ -379,7 +379,7 @@ class AssetsController extends Controller
} else {
$asset->eol_explicit = true;
}
} elseif (!$request->filled('asset_eol_date') && (($asset->model->eol) == 0)) {
} elseif (!$request->filled('asset_eol_date') && (($asset->model?->eol) == 0)) {
$asset->asset_eol_date = null;
$asset->eol_explicit = false;
}

View File

@@ -163,7 +163,7 @@ class BulkAssetsController extends Controller
$modelNames = [];
foreach($models as $model) {
$modelNames[] = $model->model->name;
$modelNames[] = $model->model?->name;
}
if ($request->filled('bulk_actions')) {
@@ -470,7 +470,7 @@ class BulkAssetsController extends Controller
*/
// Does the model have a fieldset?
if ($asset->model->fieldset) {
if ($asset->model?->fieldset) {
foreach ($asset->model->fieldset->fields as $field) {
// null custom fields

View File

@@ -229,7 +229,7 @@ class DefaultLabel extends RectangleSheet
static::writeText(
$pdf, $record->get('title'),
$textX1, 0,
'freesans', 'b', $this->textSize, 'L',
Helper::isCjk($record->get('title')) ? 'cid0cs' : 'freesans', 'b', $this->textSize, 'L',
$textW, $this->textSize,
true, 0
);
@@ -246,11 +246,12 @@ class DefaultLabel extends RectangleSheet
static::writeText(
$pdf, (($field['label']) ? $field['label'].' ' : '') . $field['value'],
$textX1, $textY,
'freesans', '', $this->textSize, 'L',
Helper::isCjk($field['label']) ? 'cid0cs' : 'freesans', '', $this->textSize, 'L',
$textW, $this->textSize,
true, 0
);
$textY += $this->textSize + self::TEXT_MARGIN;
$fieldsDone++;
}

View File

@@ -211,29 +211,36 @@ abstract class Label
*/
public final function writeText(TCPDF $pdf, $text, $x, $y, $font=null, $style=null, $size=null, $align='L', $width=null, $height=null, $squash=false, $border=0, $spacing=0)
{
$prevFamily = $pdf->getFontFamily();
$prevStyle = $pdf->getFontStyle();
$prevSizePt = $pdf->getFontSizePt();
$text = !empty($text) ? $text : '';
$fontFamily = !empty($font) ? $font : $prevFamily;
$fontStyle = !empty($style) ? $style : $prevStyle;
if ($size) { $fontSizePt = Helper::convertUnit($size, $this->getUnit(), 'pt', true);
} else { $fontSizePt = $prevSizePt;
if ($size) {
$fontSizePt = Helper::convertUnit($size, $this->getUnit(), 'pt', true);
} else {
$fontSizePt = $prevSizePt;
}
$pdf->SetFontSpacing($spacing);
$parts = collect(explode('**', $text))
->map(
function ($part, $index) use ($pdf, $fontFamily, $fontStyle, $fontSizePt) {
function ($part, $index) use ($pdf, $fontFamily, $fontStyle, $fontSizePt, $text) {
$modStyle = ($index % 2 == 1) ? 'B' : $fontStyle;
$pdf->setFont($fontFamily, $modStyle, $fontSizePt);
return [
'text' => $part,
'text_width' => $pdf->GetStringWidth($part),
'font_family' => $fontFamily,
'font_family' => Helper::isCjk($text) ? 'cid0cs' : $fontFamily,
'font_style' => $modStyle,
'font_size' => $fontSizePt,
];

View File

@@ -168,14 +168,14 @@ class AssetObserver
public function saving(Asset $asset)
{
// determine if calculated eol and then calculate it - this should only happen on a new asset
if (is_null($asset->asset_eol_date) && !is_null($asset->purchase_date) && ($asset->model->eol > 0)){
if (is_null($asset->asset_eol_date) && !is_null($asset->purchase_date) && ($asset->model?->eol > 0)) {
$asset->asset_eol_date = $asset->purchase_date->addMonths($asset->model->eol)->format('Y-m-d');
$asset->eol_explicit = false;
}
// determine if explicit and set eol_explicit to true
if (!is_null($asset->asset_eol_date) && !is_null($asset->purchase_date)) {
if($asset->model->eol > 0) {
if ($asset->model?->eol > 0) {
$months = (int) Carbon::parse($asset->asset_eol_date)->diffInMonths($asset->purchase_date, true);
if($months != $asset->model->eol) {
$asset->eol_explicit = true;
@@ -184,9 +184,9 @@ class AssetObserver
} elseif (!is_null($asset->asset_eol_date) && is_null($asset->purchase_date)) {
$asset->eol_explicit = true;
}
if ((!is_null($asset->asset_eol_date)) && (!is_null($asset->purchase_date)) && (is_null($asset->model->eol) || ($asset->model->eol == 0))) {
if ((!is_null($asset->asset_eol_date)) && (!is_null($asset->purchase_date)) && (is_null($asset->model?->eol) || ($asset->model?->eol == 0))) {
$asset->eol_explicit = true;
}
}
}

View File

@@ -74,6 +74,10 @@ class Label implements View
[0 => $template->getWidth(), 1 => $template->getHeight(), 'Rotate' => $template->getRotation()]
);
// Required for CJK languages, otherwise the embedded font can get too massive
$pdf->SetFontSubsetting(true);
// Reset parameters
$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
@@ -176,14 +180,14 @@ class Label implements View
// For fields that have multiple options, we need to combine them
// into a single field so all values are displayed.
->reduce(function ($previous, $current) {
// On the first iteration we simply return the item.
// On the first iteration, we simply return the item.
// If there is only one item to be processed for the row
// then this effectively skips everything below this if block.
if (is_null($previous)) {
return $current;
}
// At this point we are dealing with a row with multiple items being displayed.
// At this point, we are dealing with a row with multiple items being displayed.
// We need to combine the label and value of the current item with the previous item.
// The end result of this will be in this format:

View File

@@ -5,7 +5,7 @@
@endphp
@foreach($models as $model)
@if ($model->fieldset ? $model->fieldset->count() > 0 : false)
@if (($model) && ($model->fieldset ? $model->fieldset->count() > 0 : false))
@php
$anyModelHasCustomFields++;
@endphp

View File

@@ -29,6 +29,25 @@ class BulkEditAssetsTest extends TestCase
])->assertStatus(200);
}
public function test_handles_model_being_deleted()
{
$this->withoutExceptionHandling();
$user = User::factory()->viewAssets()->editAssets()->create();
$assets = Asset::factory()->count(2)->create();
$assets->first()->model->forceDelete();
$id_array = $assets->pluck('id')->toArray();
$this->actingAs($user)->post('/hardware/bulkedit', [
'ids' => $id_array,
'order' => 'asc',
'bulk_actions' => 'edit',
'sort' => 'id'
])->assertStatus(200);
}
public function test_standard_user_cannot_access_page()
{
$user = User::factory()->create();

View File

@@ -125,4 +125,32 @@ class EditAssetTest extends TestCase
$this->assertEquals($currentLocation->id, $asset->location_id);
}
public function test_handles_model_being_deleted()
{
$this->withoutExceptionHandling();
$newStatus = StatusLabel::factory()->create();
$asset = Asset::factory()->create();
$asset->model()->forceDelete();
$this->actingAs(User::factory()->viewAssets()->editAssets()->create())
->from(route('hardware.edit', $asset))
->put(route('hardware.update', $asset), [
'redirect_option' => 'index',
'purchase_date' => '2025-08-30',
'name' => 'New name',
'asset_tags' => 'New Asset Tag',
'status_id' => $newStatus->id,
// triggers potential issue in AssetObserver's saving method
'model_id' => AssetModel::factory()->create()->id,
]);
$this->assertDatabaseHas('assets', [
'id' => $asset->id,
'status_id' => $newStatus->id,
]);
}
}