Skip to content

Claude/add assets support a bs5j#570

Open
geek95dg wants to merge 15 commits intopluginsGLPI:mainfrom
geek95dg:claude/add-assets-support-ABs5j
Open

Claude/add assets support a bs5j#570
geek95dg wants to merge 15 commits intopluginsGLPI:mainfrom
geek95dg:claude/add-assets-support-ABs5j

Conversation

@geek95dg
Copy link
Copy Markdown

@geek95dg geek95dg commented Apr 8, 2026

Checklist before requesting a review

Please delete options that are not relevant.

  • I have performed a self-review of my code.
  • I have added tests (when available) that prove my fix is effective or that my feature works.
  • I have updated the CHANGELOG with a short functional description of the fix or new feature.
  • This change requires a documentation update.

Description

  • It fixes # (issue number, if applicable)
  • Here is a brief description of what this PR does

Screenshots (if appropriate):

geek95dg and others added 15 commits April 1, 2026 11:24
…nces

Custom assets (stored in glpi_assets_assets) introduced in GLPI 11.x were
missing from the Order plugin. Users could not create product references
for their user-defined asset types.

Changes:
- setup.php: Dynamically discover active custom asset definitions and add
  their concrete classes to $ORDER_TYPES
- reference.class.php: Add helper methods (getTypeClassForItemtype,
  getModelClassForItemtype, isCustomAsset, getAssetDefinitionId) to resolve
  Type/Model classes for both native and custom assets via AssetDefinition API
- reference.class.php: Update showForm(), dropdownTemplate(),
  checkIfTemplateExistsInEntity(), dropdownAllItemsByType() to use helpers
  and scope template queries by assets_assetdefinitions_id for custom assets
- ajax/referencespecifications.php: Use helpers for Type/Model/Template
  dropdown resolution
- link.class.php: Update generateNewItem() to resolve Type/Model fields
  via helpers instead of hardcoded class name convention
- hook.php, bill.class.php, order_item.class.php: Replace file_exists()
  checks with helper methods for Type/Model display

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
Add support for GLPI 11+ user-defined custom assets as product refere…
Implements OT document generation from order data, accessible via the
Actions dropdown on orders. The OT protocol follows the Polish/German
bilingual template (OT.xlsx) used for fixed asset handover documentation.

Feature flow:
1. User selects order(s) and chooses "Generate OT" from Actions
2. A popup prompts for Cost Center (MPK) value
3. System generates HTML matching the OT template layout, filled with
   delivered item data (asset name, serial, price, delivery date, supplier)
4. HTML is converted to PDF via fallback chain (wkhtmltopdf -> Chromium
   -> mPDF -> HTML fallback)
5. PDF is saved as a GLPI Document linked to the order
6. User is redirected to download the generated file

New files:
- inc/ot.class.php: PluginOrderOt class with HTML generation, PDF
  fallback chain, GLPI Document creation, and download streaming
- front/ot.form.php: Front controller for document download

Modified:
- inc/order.class.php: Register "Generate OT" massive action in
  getSpecificMassiveActions(), showMassiveActionsSubForm(), and
  processMassiveActionsForOneItemtype()

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
Document GLPI 11+ custom assets support and OT protocol PDF generation
features in the feature list and add a changelog section.

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
Remove vendor/ from .gitignore and commit composer dependencies
so the plugin works when deployed directly from git to
glpi/plugins/order/ without requiring composer install.

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
- Use $CFG_GLPI['asset_types'] as primary source for discovering GLPI 11+
  custom asset types, which is more reliable than querying AssetDefinition
  directly since GLPI populates it during its own init phase
- Remove overly strict class_exists() check from discovery that could
  fail before GLPI's dynamic class autoloader is registered
- Keep AssetDefinition query as fallback when asset_types is empty
- Fix getClasses() bug where non-existent types were kept in array
  (continue instead of unset)

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
…Name()

The discovery code was calling getConcreteClassName() which does not exist
in GLPI's AssetDefinition class. The correct method is getAssetClassName()
which returns the fully-qualified class name (e.g. Glpi\CustomAsset\Laptop)
from the AssetDefinition's system_name field.

Also wrap getClasses() type checks in try-catch for resilience against
custom asset classes with unexpected permission structures.

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
The ORM-based approach (getAssetClassName, getItemForItemtype) may fail
if GLPI's dynamic class autoloader isn't fully initialized when the
plugin loads. Added robust fallbacks:

- setup.php: Query glpi_assets_assetdefinitions directly and construct
  class names as Glpi\CustomAsset\{system_name}Asset when ORM fails
- reference.class.php: Add getCustomAssetLabel() that reads the label
  column from glpi_assets_assetdefinitions for dropdown display
- reference.class.php: Update isCustomAsset() to also match by namespace
  pattern (Glpi\CustomAsset\*) when class_exists() fails
- reference.class.php: Update getAssetDefinitionId() with direct DB
  fallback extracting system_name from class name
- Dropdown options now properly HTML-escape class names with backslashes

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
- Change page orientation from landscape to portrait (A4)
- Map "Nazwa Środka Trwałego" to the product reference name
  (from glpi_plugin_order_references.name) instead of the GLPI
  asset record name
- Serial number still comes from the delivered GLPI asset
- Adjust font sizes for narrower portrait layout

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
- Bump PLUGIN_ORDER_VERSION from 2.12.6 to 2.13.0 to clearly
  distinguish from production v2.12.4
- Update changelog version in README.md
- Add comprehensive QA_TEST_PLAN.md covering:
  - Plugin install/upgrade
  - Standard asset references (regression)
  - Custom asset references (new feature)
  - Order creation and management
  - Delivery/reception workflow
  - OT protocol generation (new feature)
  - Billing display, search, PDF backends
  - Edge cases and error handling

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
OT popup now asks for Invoice Number alongside Cost Center. The
entered value populates the "Numer faktury:" field in the generated
PDF (falls back to underscores when empty).

When an invoice number is provided, a Bill record is automatically
created with:
- Name/Number = invoice number
- Supplier = order's supplier
- Value = order's total price (tax-free)
- Status = Paid (PluginOrderBillState::PAID)
- Date/Approval date = OT generation date
- Approver = user who generated the OT
- Order = linked to the source order

Updated QA test plan with test cases 6.18-6.31 covering invoice
number input, PDF content, and bill auto-creation.

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
When generating an OT with an invoice number, the auto-created bill is now
linked to all order items (plugin_order_bills_id + plugin_order_billstates_id
set to PAID). Infocom records on delivered assets are updated with the bill
number and warranty date. The order's aggregate bill state is updated via
updateBillState(). Version bumped to 2.13.1.

https://claude.ai/code/session_01RHQ2rYmPwHepbdTrCpsDCZ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants