Skip to main content
Version: 2.0.0

Developer / API

Services

Registered as plugin components in plugin\Services::_registerComponents() and reachable via Plugin::getInstance()->get('<id>') (or the getOrders() getter for orders):

Component idServiceResponsibility
apiApiServiceBuilds the HTTP client from the current settings, converts XML between UTF-8 and windows-1250 (POHODA's expected encoding), and posts/parses XML against the mServer. sendXml() is the entry point every other service uses to talk to POHODA.
ordersOrdersServiceBuilds order/dataPack XML for export (exportOrders()) and parses listOrdersResponse XML back into arrays (importOrders()).
itemsItemsServiceBuilds stock/dataPack XML for export (exportItems()), parses listStockResponse/data-pack XML back into arrays (importItems()), and parses an uploaded XML file directly (parseItemsFromXml()).
bufferBufferServicePersists imported stock items into the pohoda_items table (saveItems()), drives the sync/import queue jobs (queueSync(), queueImport()), and imports buffered records into Craft entries (importItems()/importRecord()) using a MapperService-resolved field mapping.
mapperMapperServiceResolves the CP mapping UI's source options (built-in fields plus flattened data.* paths from a sample record's raw payload) and extracts a value for a given source from an Item record (extractValue()).
licenseLicenseServiceShared license activation/redemption service, same pattern as other yStore/craft-core plugins.

ApiService, OrdersService, and ItemsService extend AbstractService, which resolves the plugin instance and settings model lazily and allows both to be injected (setPlugin(), setSettings()) — this is what makes the services independently unit-testable outside a full Craft application (see tests/ApiServiceTest.php, tests/ItemsServiceTest.php, tests/OrdersServiceTest.php).

Data model

Yui\Pohoda\records\Item (table pohoda_items, created by m240227_000000_create_items_buffer.php) is the local stock buffer: sku, name, price, stock, vat, warehouse, data (the full POHODA payload as JSON), syncedAt, importedEntryId, importedAt. It's a plain craft\db\ActiveRecord, not a Craft element — the buffer is an internal staging table, not something queried through element APIs.

Invoice provider integration

Yui\Pohoda\providers\PohodaInvoiceProvider extends yui\craft\base\BaseInvoiceProvider and is registered on yui\craft\services\sales\InvoiceService::EVENT_REGISTER_INVOICE_PROVIDERS in Plugin::init() — only when that class exists, so Pohoda degrades gracefully without the yStore checkout/invoicing stack installed. Its getHandle() is pohoda, isEnabled() mirrors the plugin's Enable setting, and createInvoice(array $invoiceData) maps the generic invoice data array (order meta, customer, totals, items, shipping/payment as pseudo line items) into the shape OrdersService::exportOrders() expects, then calls it. To customize how invoice data maps onto a POHODA order (e.g. different VAT handling, extra line item metadata), extend or replace this provider rather than patching OrdersService — it's the single seam between the generic invoicing pipeline and Pohoda's XML format.

CP routes

Registered in plugin\Routes.php, all under the pohoda/ prefix:

  • settings (index/advanced/test-connection) → SettingsController
  • items (index/import) → ItemsController
  • license (index/redeem/revoke/activate/delete/copy-token) → shared license flow

ItemsController actions require the accessPlugin-pohoda permission in addition to a CP request; SettingsController::actionImportXml() additionally requires a POST with an uploaded xml file field.

Console commands

Items — Yui\Pohoda\console\controllers\ItemsController

# Export a JSON array of items (stdin or --input=<path>) as POHODA stock XML
php craft pohoda/items/export [--input=<path>] [--output=<path>]

# Fetch stock items from POHODA; --format=json (default) or xml
php craft pohoda/items/import [--code=<sku>] [--lastChange=<iso8601>] [--page=<n>] [--limit=<n>]
[--includeStockBalance=1] [--format=json|xml] [--output=<path>]

# Fetch stock items and save them into the local buffer table
php craft pohoda/items/sync-buffer [--code=<sku>] [--lastChange=<iso8601>] [--page=<n>]
[--limit=<n>] [--includeStockBalance=1] [--queue=1]

# Import buffered items into Craft entries using a target entry type + field mapping
php craft pohoda/items/import-buffer --entryTypeId=<id> [--siteId=<id>] [--ids=<id,id,...>]
[--map="target:source,target:source"] [--queue=1]

-i/-o/-f/-m are short aliases for --input/--output/--format/--map. --queue defaults to true on both buffer commands — pass --queue=0 to run synchronously and get an immediate count instead of a queue job id. import-buffer requires --entryTypeId; without it the command throws immediately rather than guessing a target.

Orders — Yui\Pohoda\console\controllers\OrdersController

# Export a JSON array of orders (stdin or --input=<path>) as POHODA order XML
php craft pohoda/orders/export [--input=<path>] [--output=<path>]

# Fetch orders/invoices from POHODA; --format=json (default) or xml
php craft pohoda/orders/import [--number=<n>] [--dateFrom=<Y-m-d>] [--dateTo=<Y-m-d>]
[--orderType=<type>] [--includeUnpaid=1] [--page=<n>] [--limit=<n>] [--format=json|xml]
[--output=<path>]

--orderType defaults to issuedInvoice when omitted. Both import commands auto-paginate through POHODA's requestSettings page/limit unless the caller restricts pagination through --limit combined with a single --page.

MCP tools

Registered (only when yui\mcp\Plugin is installed) on \yui\mcp\Plugin::EVENT_REGISTER_TOOLS in Plugin::init():

ToolPermissionPurpose
pohoda_export_orderWRITEExport a single order (same shape as the orders/export console command's per-item JSON) to POHODA; returns the raw response XML.
pohoda_import_ordersdefaultFetch orders from POHODA with the same filters as orders/import (orderType, number, dateFrom/dateTo, includeUnpaid, limit/page/autoPaginate); returns {count, items}.
pohoda_lookup_itemdefaultLook up stock items by code and/or lastChange (at least one required); returns {count, items} with price and stock balance. autoPaginate defaults to false here, unlike the console/service default, since lookups are expected to target a small result set.

All three delegate straight to OrdersService/ItemsService — there's no separate MCP-only business logic, so behavior changes made to those services apply to both the console commands and the MCP tools automatically.

Twig

Pohoda doesn't register a craft.pohoda template variable or any Twig extension — it has no storefront-facing rendering. All interaction happens through the CP screens, console commands, or MCP tools described above.