Cleverence Mobile SMARTS (.mslx) configuration
Cleverence "Склад 15" / "Магазин 15" runs handheld-terminal (ТСД) logic as algorithms:
a directed graph of actions. The Mobile SMARTS Panel stores each document type and
each operation as a single-line XML file with the .mslx extension. Editing these by eye
is error-prone; the failures are almost always broken transitions or wrong variable /
field names, not XML syntax. This skill encodes how the graph works and how to change it
without breaking it.
Mental model
- DocumentType
.mslx (под Documents/DocumentTypes/...) - a whole terminal workflow
(e.g. "Сборка контейнера"). Its root is <DocumentType>.
- Operation
.mslx (под Documents/Operations/...) - a reusable sub-routine called by
documents or other operations. Root is <Operation>.
- Both contain
<Actions> - the ordered list of graph nodes.
- The Panel and the MS Server work off a server database, not necessarily the git
working copy. Editing a file on disk changes nothing until the config is transferred to
the server (Сервис -> Сравнение конфигураций, or copying into the live DB + restart).
If the Panel shows old behaviour after your edit, suspect a stale/never-transferred
file before suspecting your change.
The single most important rule: CL_ copies of vendor operations
Vendor operations (typical Cleverence обработчики, usually under Operations/EN/...,
Operations/Основные/... etc.) get overwritten on Cleverence updates. Editing them
directly is like editing a vendor 1C extension - your change disappears on the next update.
So:
| What |
Rule |
| Our own document type (e.g. "Сборка контейнера") |
Edit in place. Do not clone. |
Our own operation (in the project root Operations/) |
Edit in place. |
| A vendor/typical operation we need to change |
Make a copy CL_<Name> (placement below), edit the copy, and in the caller switch operationName to CL_<Name>. |
| A new operation |
Prefix CL_ (latin). |
Copy only the operations you actually change. If the change is inside a nested vendor
operation, copy that one and repoint its CL_ parent at it - do not clone the whole chain.
Where to put a CL_ copy. Put it in your own branch of the operations tree -
Documents/Operations/ (the root) - not inside the vendor subfolder it was copied from
(Documents/Operations/EN/...). The Panel resolves a call by the operation's name, not by
its file path, so a CL_<Name> in Operations/ fully serves callers that use
operationName="CL_<Name>". Keeping the copy in the vendor subfolder (a) puts it among files
that get overwritten on update, and (b) risks two files with the same name if the Panel
later re-exports the operation into the root - a duplicate that conflicts on import. So: after
creating/moving the copy to Operations/, delete any stale same-name file left in the
vendor subfolder.
How the action graph flows
Every action decides where control goes next. Read references/graph-mechanics.md for the
full rules; the essentials:
- Sequential fall-through: an empty
nextDirection="" means "go to the next action in
document order". This is why the physical order of <Actions> matters - inserting an
action in the wrong place silently changes the flow.
- Named transitions point to an action's
name. Resolution is case-insensitive
(a button direction "Просмотр факт" resolves to action name="Просмотр Факт"). So if a
transition "is not found", the cause is almost never letter-case - it is a genuinely
missing action (often a stale file on the server).
- ConditionAction branches with
yesDirection (TRUE) and noDirection (FALSE); empty
means fall through to the next action.
- QuestionYesNoAction branches with
yesDirection / noDirection.
- QuestionAction (a menu) has three parallel arrays -
Buttons, ButtonTexts,
ButtonDirections - matched by index. They must stay the same length; a button whose
ButtonDirection names a non-existent action throws "действие для перехода не найдено".
- Built-in targets that are not action names:
back, return, abort, exit, home,
process zero, and "".
indent = visual nesting in the Panel tree, not control flow. Each action carries an
integer indent. Logically subordinate actions (a process zero branch under the scan
window, the body executed inside a condition) must have indent greater than their
parent - they appear shifted right in the Panel algorithm tree. Flow is driven by
nextDirection/named transitions, not by indent; but leaving a flat indent=0 on
nested actions renders the structure wrong/flat in the Panel and is a real defect to fix.
When you copy or hand-edit a .mslx, preserve/set indent on the nested actions (it is
easy to lose it on a copy). mslx_inspect.py indents its dump by this attribute, so a flat
structure shows up at a glance.
Calling another operation: parameter mapping
OperationAction invokes a sub-operation by operationName and maps variables explicitly:
InKeys / InValues - the sub-operation's variable name / the caller's expression.
Expressions are wrapped in braces: InValues = {GO.GetBarcodeData(ScannedBarcode)}.
OutKeys / OutValues - the sub-operation's result variable / the caller's variable.
Many shared variables (BarcodeData, IdentificationCode, CurrentItem, ...) are global
to the session, so some calls pass nothing and rely on globals. When in doubt, look at how
the operation is already called elsewhere (grep for its operationName) and copy that
contract verbatim - guessing variable names is the #1 cause of "scan does nothing".
Calling 1C online from the terminal
To run a 1C function live during a scan, use an InvokeMethodAction against the 1C
connector. The function name you pass must be a method of the integration data processor
(вендорская ИнтеграционнаяОбработка_*), and it must return a ТаблицаЗначений (not JSON).
The full mechanism, the thin-wrapper pattern (with vendor markers), and what is not an
online call (the "Список произвольных кодов" is field mapping, not a call) are in
references/online-1c-call.md.
Marking codes (КМ / КИЗ) and document lines
The marking code on a document line lives in Item.МаркаИСМП (and Item.ГрупповаяУпаковка
for aggregates) - not Item.Марка. You match against the recognised IdentificationCode,
which is produced by GetIdentificationCode from BarcodeData, not against the raw scanned
string. Reuse the ready operations (FindMCInDocument, DeleteCurrentItemFromDocument,
IsMarkingCode) instead of hand-writing queries. See
references/km-and-document-operations.md.
Editing methodology (do this, in this order)
- Inspect first. Run the bundled tool to see the real graph and current links:
PYTHONIOENCODING=utf-8 python scripts/mslx_inspect.py "<file>.mslx"
It dumps every action (type, name, operationName, directions, In/Out mapping) and then
validates: XML well-formedness, that every transition resolves, and that menu button
arrays are balanced.
- Find the proven pattern. Before writing new graph logic, grep the existing operations
for one that already does it and copy its action structure and variable contract. The
codebase almost always has a working precedent (scanning, finding a line, deleting a line,
confirming, calling 1C). Reusing it beats inventing.
- Make point edits.
.mslx is one long line; use exact-string Edit, keep ids stable
where you can, and keep the action order consistent with the fall-through you intend.
- Re-inspect. Run
mslx_inspect.py ... --validate again. Zero dangling transitions and
balanced button arrays is the bar before you hand it back.
- Remember the transfer step. A validated file on disk is not yet live - it must reach
the MS Server. Tell the user to transfer it and to confirm by checking that a changed
operationName (e.g. CL_...) shows up in the Panel.
When a scan "does nothing" on the TSD
Before suspecting the graph, rule out the input itself - the graph is usually innocent:
Ctrl+V into the debugger window is NOT a scan event. A scan window catches input via a
KeyToAction barcode="{any}" KeyJump, which fires on a scan event. Pasting text into the
field with Ctrl+V is keyboard input - it does not trigger the barcode KeyJump, so
"nothing happens". Use the debugger's emulate-barcode function (a dedicated barcode input),
or a real scanner.
- DataMatrix loses its GS separators on copy-paste. A ЧЗ marking code (DataMatrix) contains
the GS control char (ASCII 29). Clipboard/Notepad strips it, so even if the input lands,
GO.GetBarcodeData() won't recognise the КМ structure. Only a real scanner (or the emulator)
preserves GS.
- The config may not be on the server. The debugger runs the server copy; an edited file in
the repo is not live until transferred (Сервис -> Сравнение конфигураций).
- Only after these: check the graph. Confirm the scan window has
KeyToAction barcode="{any}"
pointing at the scan-handling action, and (with a breakpoint in the debugger) whether that
action is even reached. If it is reached but bails out, inspect BarcodeData - the code was
read but not recognised.
Linking a TSD document back to its 1C document (dedup on completion)
When a TSD document must, on completion, update an existing 1C document instead of creating
a new one, the back-link is a Panel setting, not graph logic: in the БП open "Настройка
загрузки полей шапки документа" and the rule whose target (приемник) is the Ссылка field,
match mode Поиск по GUID. The source attribute of that rule is a classic trap:
Идентификатор - the MS document's own Id. This is the correct source for dedup. It
is stable for one TSD document and is exactly what the vendor completion code resolves the 1C
reference from (ШапкаДокумента.Ид). Use this.
Идентификатор исходных документов (ИдИсходныхДокументов) - wrong for the back-link
of a TSD-created document. If an online step creates/re-creates the 1C document and writes its
GUID here, a fresh GUID can arrive on every completion -> the GUID search never matches ->
a new 1C document is created each time = duplicates (often without a warehouse). This
attribute is for the "document assembled from several 1C documents" case, not the back-link.
Symptom this fixes: every завершение on the TSD spawns a second 1C document. Root cause is
almost always the Ссылка rule pointing at Идентификатор исходных документов instead of
Идентификатор. The vendor completion path only ever resolves the 1C ref from
ШапкаДокумента.Ид - writing a GUID into ИдИсходныхДокументов does nothing for dedup.
Caveat for TSD-created docs: their MS Id is new_<guid>. A hand-rolled
Документы[Тип].ПолучитьСсылку(Новый УникальныйИдентификатор(Ид)) throws on the new_ prefix
(invalid GUID) and, inside a bare Попытка, silently falls through to creating a duplicate; the
Поиск по GUID rule handles the prefix correctly.
Reference files
references/graph-mechanics.md - action types, every transition attribute, fall-through,
button arrays, KeyJumps, common caveats. Read when editing graph flow.
references/online-1c-call.md - the InvokeMethodAction -> integration-processor ->
ТаблицаЗначений mechanism, the wrapper pattern, what is not an online call.
references/km-and-document-operations.md - КМ line fields, IdentificationCode, the ready
find/delete/recognise operations and how to chain them.
Constraints in 1C-integration projects
Vendor extensions and 1C extensions are not edited directly - mark project insertions and
prefer copies/wrappers. In this family of projects code and docs avoid the letter "е" and
long dashes. Confirm destructive or shared-state actions (config transfer to Test/Prod)
before doing them.
1---2name: cleverence-mslx3description: Read, understand and safely edit Cleverence Mobile SMARTS (Склад 15 / Магазин 15) configuration stored as .mslx files - the XML algorithm graphs that drive handheld terminal (ТСД) workflows in 1C integration projects. Use this skill whenever the task touches Cleverence / Mobile SMARTS / "Клеверенс" / ТСД algorithms, .mslx files, document types or operations (обработчики) on the terminal, menu/scan/КМ logic on a scanner, calling 1C online from the TSD, or "почему скан не срабатывает / действие не найдено / кнопка не работает" on a handheld - even if the user does not say ".mslx" explicitly. Covers the action graph, transition chaining, OperationAction parameter mapping, the online 1C call mechanism, marking-code (КМ) line operations, and the CL_-copy rule for not breaking vendor operations on update.4---56# Cleverence Mobile SMARTS (.mslx) configuration78Cleverence "Склад 15" / "Магазин 15" runs handheld-terminal (ТСД) logic as **algorithms**:9a directed graph of **actions**. The Mobile SMARTS Panel stores each document type and10each operation as a single-line XML file with the `.mslx` extension. Editing these by eye11is error-prone; the failures are almost always *broken transitions* or *wrong variable /12field names*, not XML syntax. This skill encodes how the graph works and how to change it13without breaking it.1415## Mental model1617- **DocumentType** `.mslx` (под `Documents/DocumentTypes/...`) - a whole terminal workflow18 (e.g. "Сборка контейнера"). Its root is `<DocumentType>`.19- **Operation** `.mslx` (под `Documents/Operations/...`) - a reusable sub-routine called by20 documents or other operations. Root is `<Operation>`.21- Both contain `<Actions>` - the ordered list of graph nodes.22- The Panel and the MS Server work off a **server database**, not necessarily the git23 working copy. Editing a file on disk changes nothing until the config is transferred to24 the server (Сервис -> Сравнение конфигураций, or copying into the live DB + restart).25 **If the Panel shows old behaviour after your edit, suspect a stale/never-transferred26 file before suspecting your change.**2728## The single most important rule: CL_ copies of vendor operations2930Vendor operations (typical Cleverence обработчики, usually under `Operations/EN/...`,31`Operations/Основные/...` etc.) get **overwritten on Cleverence updates**. Editing them32directly is like editing a vendor 1C extension - your change disappears on the next update.3334So:3536| What | Rule |37|------|------|38| Our own document type (e.g. "Сборка контейнера") | Edit **in place**. Do not clone. |39| Our own operation (in the project root `Operations/`) | Edit **in place**. |40| A **vendor/typical** operation we need to change | Make a copy `CL_<Name>` (placement below), edit the copy, and in the caller switch `operationName` to `CL_<Name>`. |41| A new operation | Prefix `CL_` (latin). |4243Copy only the operations you actually change. If the change is inside a nested vendor44operation, copy that one and repoint its `CL_` parent at it - do not clone the whole chain.4546**Where to put a CL_ copy.** Put it in your own branch of the operations tree -47`Documents/Operations/` (the root) - **not** inside the vendor subfolder it was copied from48(`Documents/Operations/EN/...`). The Panel resolves a call by the operation's `name`, not by49its file path, so a `CL_<Name>` in `Operations/` fully serves callers that use50`operationName="CL_<Name>"`. Keeping the copy in the vendor subfolder (a) puts it among files51that get overwritten on update, and (b) risks **two files with the same `name`** if the Panel52later re-exports the operation into the root - a duplicate that conflicts on import. So: after53creating/moving the copy to `Operations/`, delete any stale same-`name` file left in the54vendor subfolder.5556## How the action graph flows5758Every action decides where control goes next. Read `references/graph-mechanics.md` for the59full rules; the essentials:6061- **Sequential fall-through**: an empty `nextDirection=""` means "go to the next action in62 document order". This is why the **physical order of `<Actions>` matters** - inserting an63 action in the wrong place silently changes the flow.64- **Named transitions** point to an action's `name`. Resolution is **case-insensitive**65 (a button direction `"Просмотр факт"` resolves to action `name="Просмотр Факт"`). So if a66 transition "is not found", the cause is almost never letter-case - it is a genuinely67 missing action (often a stale file on the server).68- **ConditionAction** branches with `yesDirection` (TRUE) and `noDirection` (FALSE); empty69 means fall through to the next action.70- **QuestionYesNoAction** branches with `yesDirection` / `noDirection`.71- **QuestionAction** (a menu) has three parallel arrays - `Buttons`, `ButtonTexts`,72 `ButtonDirections` - matched by index. They **must stay the same length**; a button whose73 `ButtonDirection` names a non-existent action throws "действие для перехода не найдено".74- Built-in targets that are not action names: `back`, `return`, `abort`, `exit`, `home`,75 `process zero`, and `""`.76- **`indent` = visual nesting in the Panel tree, not control flow.** Each action carries an77 integer `indent`. Logically subordinate actions (a `process zero` branch under the scan78 window, the body executed inside a condition) must have `indent` **greater** than their79 parent - they appear *shifted right* in the Panel algorithm tree. Flow is driven by80 `nextDirection`/named transitions, **not** by `indent`; but leaving a flat `indent=0` on81 nested actions renders the structure wrong/flat in the Panel and is a real defect to fix.82 When you copy or hand-edit a `.mslx`, **preserve/set `indent`** on the nested actions (it is83 easy to lose it on a copy). `mslx_inspect.py` indents its dump by this attribute, so a flat84 structure shows up at a glance.8586## Calling another operation: parameter mapping8788`OperationAction` invokes a sub-operation by `operationName` and maps variables explicitly:8990- `InKeys` / `InValues` - the sub-operation's variable name / the caller's expression.91 Expressions are wrapped in braces: `InValues = {GO.GetBarcodeData(ScannedBarcode)}`.92- `OutKeys` / `OutValues` - the sub-operation's result variable / the caller's variable.9394Many shared variables (`BarcodeData`, `IdentificationCode`, `CurrentItem`, ...) are global95to the session, so some calls pass nothing and rely on globals. When in doubt, look at how96the operation is already called elsewhere (grep for its `operationName`) and copy that97contract verbatim - guessing variable names is the #1 cause of "scan does nothing".9899## Calling 1C online from the terminal100101To run a 1C function live during a scan, use an `InvokeMethodAction` against the 1C102connector. The function name you pass must be a **method of the integration data processor**103(вендорская `ИнтеграционнаяОбработка_*`), and it must return a `ТаблицаЗначений` (not JSON).104The full mechanism, the thin-wrapper pattern (with vendor markers), and what is *not* an105online call (the "Список произвольных кодов" is field mapping, not a call) are in106`references/online-1c-call.md`.107108## Marking codes (КМ / КИЗ) and document lines109110The marking code on a document line lives in `Item.МаркаИСМП` (and `Item.ГрупповаяУпаковка`111for aggregates) - **not** `Item.Марка`. You match against the recognised `IdentificationCode`,112which is produced by `GetIdentificationCode` from `BarcodeData`, not against the raw scanned113string. Reuse the ready operations (`FindMCInDocument`, `DeleteCurrentItemFromDocument`,114`IsMarkingCode`) instead of hand-writing queries. See115`references/km-and-document-operations.md`.116117## Editing methodology (do this, in this order)1181191. **Inspect first.** Run the bundled tool to see the real graph and current links:120 ```bash121 PYTHONIOENCODING=utf-8 python scripts/mslx_inspect.py "<file>.mslx"122 ```123 It dumps every action (type, name, operationName, directions, In/Out mapping) and then124 validates: XML well-formedness, that every transition resolves, and that menu button125 arrays are balanced.1262. **Find the proven pattern.** Before writing new graph logic, grep the existing operations127 for one that already does it and copy its action structure and variable contract. The128 codebase almost always has a working precedent (scanning, finding a line, deleting a line,129 confirming, calling 1C). Reusing it beats inventing.1303. **Make point edits.** `.mslx` is one long line; use exact-string Edit, keep ids stable131 where you can, and keep the action order consistent with the fall-through you intend.1324. **Re-inspect.** Run `mslx_inspect.py ... --validate` again. Zero dangling transitions and133 balanced button arrays is the bar before you hand it back.1345. **Remember the transfer step.** A validated file on disk is not yet live - it must reach135 the MS Server. Tell the user to transfer it and to confirm by checking that a changed136 `operationName` (e.g. `CL_...`) shows up in the Panel.137138## When a scan "does nothing" on the TSD139140Before suspecting the graph, rule out the input itself - the graph is usually innocent:141142- **`Ctrl+V` into the debugger window is NOT a scan event.** A scan window catches input via a143 `KeyToAction barcode="{any}"` KeyJump, which fires on a *scan event*. Pasting text into the144 field with `Ctrl+V` is keyboard input - it does not trigger the `barcode` KeyJump, so145 "nothing happens". Use the debugger's *emulate-barcode* function (a dedicated barcode input),146 or a real scanner.147- **DataMatrix loses its GS separators on copy-paste.** A ЧЗ marking code (DataMatrix) contains148 the GS control char (ASCII 29). Clipboard/Notepad strips it, so even if the input lands,149 `GO.GetBarcodeData()` won't recognise the КМ structure. Only a real scanner (or the emulator)150 preserves GS.151- **The config may not be on the server.** The debugger runs the server copy; an edited file in152 the repo is not live until transferred (Сервис -> Сравнение конфигураций).153- Only after these: check the graph. Confirm the scan window has `KeyToAction barcode="{any}"`154 pointing at the scan-handling action, and (with a breakpoint in the debugger) whether that155 action is even reached. If it is reached but bails out, inspect `BarcodeData` - the code was156 read but not recognised.157158## Linking a TSD document back to its 1C document (dedup on completion)159160When a TSD document must, on completion, update an **existing** 1C document instead of creating161a new one, the back-link is a Panel **setting**, not graph logic: in the БП open *"Настройка162загрузки полей шапки документа"* and the rule whose target (приемник) is the `Ссылка` field,163match mode **Поиск по GUID**. The **source attribute** of that rule is a classic trap:164165- **`Идентификатор`** - the MS document's own Id. This is the **correct** source for dedup. It166 is stable for one TSD document and is exactly what the vendor completion code resolves the 1C167 reference from (`ШапкаДокумента.Ид`). Use this.168- **`Идентификатор исходных документов`** (`ИдИсходныхДокументов`) - **wrong** for the back-link169 of a TSD-created document. If an online step creates/re-creates the 1C document and writes its170 GUID here, a **fresh GUID can arrive on every completion** -> the GUID search never matches ->171 a new 1C document is created each time = **duplicates** (often without a warehouse). This172 attribute is for the "document assembled from several 1C documents" case, not the back-link.173174Symptom this fixes: every *завершение* on the TSD spawns a second 1C document. Root cause is175almost always the `Ссылка` rule pointing at *Идентификатор исходных документов* instead of176*Идентификатор*. The vendor completion path only ever resolves the 1C ref from177`ШапкаДокумента.Ид` - writing a GUID into `ИдИсходныхДокументов` does nothing for dedup.178179Caveat for TSD-created docs: their MS Id is `new_<guid>`. A hand-rolled180`Документы[Тип].ПолучитьСсылку(Новый УникальныйИдентификатор(Ид))` throws on the `new_` prefix181(invalid GUID) and, inside a bare `Попытка`, silently falls through to creating a duplicate; the182*Поиск по GUID* rule handles the prefix correctly.183184## Reference files185186- `references/graph-mechanics.md` - action types, every transition attribute, fall-through,187 button arrays, KeyJumps, common caveats. Read when editing graph flow.188- `references/online-1c-call.md` - the InvokeMethodAction -> integration-processor ->189 ТаблицаЗначений mechanism, the wrapper pattern, what is not an online call.190- `references/km-and-document-operations.md` - КМ line fields, IdentificationCode, the ready191 find/delete/recognise operations and how to chain them.192193## Constraints in 1C-integration projects194195Vendor extensions and 1C extensions are not edited directly - mark project insertions and196prefer copies/wrappers. In this family of projects code and docs avoid the letter "е" and197long dashes. Confirm destructive or shared-state actions (config transfer to Test/Prod)198before doing them.