PMIS AI Browser Operator
Language / Jezik: English | Slovenščina
Provides command provenance, a queue, and permission-aware AI action execution in Odoo 18 Community. Authorized direct Discuss messages become command records that the operator can review, execute through the normal Odoo UI, and complete with an audited result.
The module provides authorization, tracking, Odoo-managed operating guidance, a protected server-side ChatGPT connection, resumable background AI orchestration, and an Odoo action executor. The default connection uses company-scoped workspace Codex access tokens. Imported OAuth sessions, an external worker, and manual ChatGPT browser handoff remain optional advanced workflows.
For step-by-step configuration and daily operation, see the User Manual.
Features
Queue and audit trail
Provides an oldest-first queue of Active Work (pending and in-progress), bot and state grouping, text and source-ID search, eligibility reasons, captured text, bot progress/outcomes, and audit history.
Opens the queue as a kanban grouped by state, with a list view also available. Cards show the instruction preview, bot, requester, capture time, and current eligibility. Open a card to inspect the full command and use its lifecycle actions; dragging cards between states is disabled.
Revalidates configuration, membership, identity, and the unchanged source message before starting a command.
Retains command provenance and text snapshots when the source message changes or is deleted, and prevents provenance edits through ORM/RPC, including by managers.
Records command capture, state changes, and result-note updates as immutable audit events with the acting user and time.
Restricts execution lifecycle actions to the assigned bot, serializes command updates, and freezes terminal records.
Identifies the normalized captured instruction with a stored SHA-256 digest.
Configuration
Reusable business skills
One bot can select and combine multiple skills for different commands. Managers maintain Configuration → AI Skills and assign up to 20 workflows on each bot's Skills tab. Starter workflows cover CRM, sale quotations, and sale orders; they are not assigned automatically and do not install optional business apps.
Each skill has a technical code, selection summary, instructions, automatic version, and JSON capability requirements. For example, {"sale.order": ["read", "create", "action:action_confirm"]} requires all listed operations to appear in the bot's ordinary-user executor capabilities. Use search, read, create, write, or action:<method>. An empty map provides general guidance without requiring a particular app. Requirements control skill availability; they do not restrict or grant executor operations.
Starting a command with execution enabled freezes its available assigned skills. The prompt contains their summaries; the AI selects a workflow using the existing odoo_executor tool with {"operation": "load_skill", "skill": "<code>"}. Selected frozen instructions then enter subsequent prompts. Selection creates an audit event and consumes a tool call. Repeated selection creates no duplicate event. Several skills may be loaded for one task. The same contract works in all connected runtimes, and the prepared manual prompt shows the same catalog.
Changing guidance increments its version and affects future commands. Started commands retain their snapshots; new assignments do not enter existing runs. Loading rechecks current assignment, archival status, and capability requirements. Already loaded guidance remains frozen: cancel active commands to stop their work. No snapshots are backfilled into commands started before the module upgrade.
Operators can read skills assigned to their own bot but cannot maintain them. Managers can maintain the catalog; archival replaces deletion. Skills grant no business permission, company access, or authority beyond the captured request. Quotation preparation never implies order confirmation. Sending quotations, invoicing, delivery, cancellation, and confirmed-order edits remain unsupported.
Dependencies and access
The module depends on Odoo Discuss (mail) and base_setup. Supported Odoo actions execute through its built-in executor. Automatic AI planning runs on the Odoo server by default. The Linux server needs Codex CLI 0.159.3 or later, available on the Odoo service's PATH or through an administrator-configured absolute executable path. Install it using the official Codex distribution; it is not a Python dependency and therefore is not installed by requirements.txt. No user computer needs software installation. Working cron workers and outbound HTTPS to OpenAI are required. Provider eligibility and workspace permissions still apply.
Assign Browser Operator to each bot user that needs queue access. Assign Browser Operator Manager to the people managing bot configurations and command authorizations; this group includes Browser Operator but does not grant Settings administration or access to private Discuss message content.
Managers can inspect every captured command and its audit history, including private command text. This role must therefore be granted only to trusted command administrators. It does not grant general access to the private Discuss history. Managers can cancel pending or in-progress work with a required reason or add an administrative observation to active work. These focused actions create explicitly typed audit events with the actual actor and timestamp. They never write the bot's progress/outcome, become additional instructions, or send chat messages. Managers cannot start, reject, complete, or fail another bot's commands. Other operators can read and update only commands addressed to their own Odoo user. A manager who is also the assigned bot acts under that bot identity. Requesters must be active internal users but do not need an operator group to send commands. Internal users without an operator group, portal users, and public users have no queue access through this module.
Configure business groups and allowed companies through normal user settings. No permissions are assigned to configured users automatically. Discuss is shared across companies: a command authorization identifies a user and channel, not a company grant. Business operations remain subject to the bot's normal access rights and company access.
Bot and requester setup
Create a dedicated internal Odoo user, such as PMIS AI Bot, using normal user settings. Assign its operator group, business permissions, and companies. UID 1 cannot be configured as a bot. Installation creates no bot users.
As a manager, open PMIS AI Browser Operator → Configuration → Browser Bots and create a bot configuration linked to that user.
Have each requester establish a direct Discuss conversation with the bot. Both users must be active and have distinct partners.
Add the requester under Authorized Command Channels. An existing unique valid chat is selected automatically. When several exist, select the correct Direct Chat. Use Resolve Direct Chat on the authorization form to resolve an existing conversation after it has been established.
Activate only structurally valid authorizations. An inactive row can be saved while awaiting a conversation. The validation fields distinguish structural validity from enabled capture; both the bot and authorization must be active to capture commands.
Archive bot configurations and authorizations when they are no longer needed; the module's access rights do not permit deleting them.
Usage
Connected ChatGPT execution
Operating instructions and captured business requests stay configured in Odoo; no ChatGPT custom instructions or manual JSON preparation are needed.
The default Company Codex Access Token runtime uses a workspace credential configured per company in Settings → AI Browser Operator. It requires no OAuth popup, user-side helper, Odoo API key, or changes to ChatGPT instructions.
In the ChatGPT Business or Enterprise workspace, enable access-token creation and local Codex access for the workflow owner. Create a token with Codex scope and a finite expiration. A Workspace Agents token or Platform API key is not a substitute. See OpenAI access-token documentation.
As an Odoo Settings administrator, select the intended company, open Settings → AI Browser Operator, enter New Codex Access Token, and save. The field is write-only: accepted tokens are never reloaded into the form. Leaving it blank retains the current token. Use HTTPS and protect the server.
Configure Codex Executable if it is not on the Odoo service's PATH. This executable setting applies to the entire server, not a single company.
Select Refresh Models. Catalog listing does not verify entitlement. Test Inference explicitly sends a small synthetic request using the first catalog model, consuming workspace usage but sending no business records.
On the bot, select Company Codex Access Token, set its execution company or retain the bot user's default company, then select Refresh Company Connection. Select a catalog model and enable AI Enabled and Odoo Executor. The execution company must be allowed for that Odoo user.
Only Settings administrators assigned to a company can replace or remove its token. Operators and operator managers may refresh the bot's nonsecret catalog, but cannot retrieve its credential. Tokens represent their ChatGPT workspace creator; sharing a company connection does not impersonate the Odoo requester. Replace expired or revoked tokens in Settings. Replacement or removal stops saved work on the next worker step; already committed business changes remain. Revoke removed tokens in ChatGPT as well. A changed execution company or assigned bot user invalidates the journal binding; administrators must review and cancel old work instead of transferring uncertain mutations to another identity.
The scheduled action PMIS AI: Process Server Instructions runs every minute, advancing each active bot by at most one planning step per invocation. Codex only proposes a bounded structured operation or report. Odoo executes proposed actions in short ordinary-user transactions, saves their receipts, and supplies them to the next planning step. Local shell, plugins, image-file access, web search, hooks, and subagents are disabled; the child runtime has private temporary configuration and restricted filesystem read access. The process exits after each request.
Imported OAuth Session (Advanced) retains the generic OpenAI remote-server transfer workflow. Its Configure AI Connection page explains local OAuth authorization and secure credential upload. External Companion (Advanced) retains the standalone runtime using --sign-in and the assigned bot user's privately prompted Odoo API key. These optional modes do not share claims with the company-token runtime and are not required for workspace-token operation.
After connection, refresh the bot's AI Connection tab, select an account model, and enable AI Enabled. With AI Auto Run off, a manager or assigned bot queues each valid pending command using Queue AI. With it on, eligible pending Discuss commands are claimed automatically. Managers can queue work, but all actual calls execute as the assigned ordinary Odoo bot user.
The selected runtime sends Odoo operating guidance, captured commands, capabilities, and necessary tool results to OpenAI. Company-token requests use the supported Codex app-server protocol; imported-session requests use the Responses API. Planning results are validated before permission-aware executor calls. It supports the installed contact, CRM, sales, and website tools below. No shell, arbitrary RPC, unrestricted ORM, or ChatGPT browser-cookie endpoint is available to the model. Provider inference happens outside Odoo database transactions.
Both Odoo and the selected runtime bound work to the configured tool count (1–50). Odoo rechecks authority, execution/company permissions, and the run fence before each call and rejects runs older than 15 minutes. Each completed mutation commits independently with its receipt: a later failure does not undo earlier changes. The final model report is saved as Awaiting Review, not automatically Done. Inspect execution receipts and changed records, then complete the normal bot lifecycle. Reports alone are not proof of successful business execution.
Account eligibility, model choices, granted plan-use permission, and usage limits come from OpenAI. A ChatGPT identity login alone is insufficient. The runtime reports missing permissions and account/usage limits without repeatedly signing in or retrying quota failures. This integration cannot guarantee support for every ChatGPT plan; review app access and limits in ChatGPT Settings → Usage.
Runtime controls and privacy
A protected restart journal saves complete response items and original call IDs before execution. A lost mutation response replays its receipt instead of creating a duplicate operation. Claim identifiers also make lost claim responses recoverable. The server worker resumes that journal automatically after network interruptions, with a retry delay. Permission and quota failures stop automatic retries; use Refresh Company Connection (or Refresh Server Connection for an imported OAuth session) after resolving the account restriction. The 15-minute run fence still applies across scheduled turns. A successful report clears the journal. Cancellation prevents further calls but cannot undo changes or recall context already sent to OpenAI.
Company tokens reside under <odoo-data-dir>/pmis_ai_codex/<database-digest>/<company-id>/. Company-runtime business-data journals are separate, under <odoo-data-dir>/pmis_ai_codex_journals/pmis_ai_server/<database-digest>/<bot-id>/. Imported-session access/refresh/ID tokens and journals reside under <odoo-data-dir>/pmis_ai_server/<database-digest>/<bot-id>/, in owner-only directories and atomically replaced files. They are not stored in ORM fields, attachments, browser storage, repository files, or diagnostic logs. Database names/UUIDs separate profiles, and a stored binding prevents silently reusing journals after changing the assigned Odoo user or execution company. Protect the runtime directory and its backups; multi-node deployments require shared protected storage with working file locks. Do not copy live rotating sessions between workers. Uploading over HTTPS transfers secrets to the server operator's trust boundary.
The optional external companion stores its profile under ~/.config/pmis-ai-operator/<profile>/. Its --once, --sign-out, and Ctrl+C controls apply only to that external runtime. The Odoo connection status shows runtime activity, not a guarantee of account eligibility or remaining quota.
Implementation references: official registration and sign-in, model inference, and preview limitations.
Odoo action executor
As a manager, enable Execution Enabled on a bot's Odoo Executor tab. Select an Execution Company allowed for that user, or leave it unset to use the bot user's default company. Configure normal Odoo business groups separately; enabling this setting grants no business permissions.
After Claim / Start, the assigned bot can use Execute Prepared Action to inspect available operations, submit a structured action request, and review its result. This is a manual integration/testing dialog, not a natural-language AI connection. New Call intentionally starts another request; repeating the same mutation call ID returns its existing receipt without repeating the change. Keep the same call ID when retrying a request whose response was lost.
Supported installed apps become available according to the bot user's model ACLs and field groups. Every execution checks current command provenance, user and bot activation, operator membership, claimed state, enabled execution, record rules, related-record access, and company scope. Managers cannot execute another bot's command. The executor clears caller-supplied context and elevated mode before business access. Each call uses exactly one configured company.
The initial registry supports:
Contacts: search, read, create, and edit supported contact/address fields.
CRM: search, read, create, and update leads/opportunities, including stages and expected revenue; mark an opportunity won through Odoo's standard action.
Sales: create and edit draft quotations and their lines, read products and pricelists, and confirm quotations through Odoo's standard action. Confirmed orders and their lines are excluded from draft-edit tools.
Website: inspect pages and websites, replace static content inside a uniquely identified element within the page's wrap, update website-specific page metadata/publishing status, and create or update menus. Shared page content uses Odoo's website copy-on-write behavior for an explicitly selected website. Existing QWeb layout directives remain intact; supplied content is sanitized and cannot introduce QWeb directives. Arbitrary view/template editing is not exposed.
These apps are optional: installation of this addon does not install CRM, Sales, or Website. Unsupported models, fields, methods, raw Python/SQL, deletion, credential management, and arbitrary context are unavailable. Additional addons can extend the private pmis.ai.command.executor._model_specs() registry with reviewed business surfaces; ordinary user/company checks still apply.
Successful mutations and their immutable receipts/audit events share one database transaction. Failure rolls back the call's database changes. Receipts retain operation, actor, company, call ID, request digest, and affected record IDs; they do not retain submitted field values or business-record read snapshots. Current access and authority are rechecked before replaying a receipt. Searches are limited to 50 records, offset 10,000, direct supported fields, and bounded JSON requests/results. Nested relational write commands are unavailable; create quotation lines through separate calls.
An installed addon can add side effects to ordinary Odoo actions, including order confirmation. Database rollback cannot undo remote effects already sent by such an extension. Audit receipts prove accepted tool calls, not external delivery or natural-language intent. The AI/operator must keep each call within the captured instruction's scope; Odoo does not infer that scope from prose.
Connector contract
Authenticate as the assigned bot using Odoo's normal session/RPC mechanism. For a claimed command, action_get_executor_tools() returns function schemas and current model/field/action capabilities. A connector passes the model's structured request to action_execute_tool(call_id, request) and returns its result as the function-call output. It supplies a stable unique call ID per mutation, keeps provider calls outside the Odoo transaction, and refreshes command authority before each subsequent tool call. It never selects another Odoo execution identity or supplies elevated context.
For example, a synthetic contact request is:
{"operation": "create", "model": "res.partner",
"values": {"name": "Synthetic contact"}}
A website content request uses operation: edit_page, model: website.page, one page ID, and values containing element_id and html. For shared pages, also supply website_id. The returned page ID identifies the website-specific copy and may differ from the submitted page ID.
The company-token server worker implements this contract with structured Codex planning. The advanced OAuth worker and optional companion use streamed Responses orchestration. The executor works independently of either provider and performs no AI-provider requests inside its business transactions.
ChatGPT browser handoff
Managers maintain Operating Instructions on the bot's ChatGPT Instructions tab. This guidance describes how to perform and report authorized work; it cannot authorize additional business operations or expand the Odoo user's permissions. Do not enter passwords, tokens, or other credentials in this field.
Open ChatGPT / Sign In opens ChatGPT in another browser tab. Sign in there with the intended account and select the intended workspace. Authentication stays in that browser profile: Odoo stores no ChatGPT credentials, cannot verify the active account, and does not share its session with other Odoo users.
After Claim / Start, the assigned bot can choose Prepare ChatGPT Instructions. Review the generated prompt, use Copy Instructions, open ChatGPT, and paste it into a new conversation. The prompt includes execution boundaries, command and source-message IDs, the command digest, current manager-configured guidance, and the immutable captured business command. It excludes configuration notes, bot results, and administrative observations. No ChatGPT custom instructions are required. Preparing the prompt neither changes the command state nor sends data. Sending it in ChatGPT shares its content with that account's service.
The server rejects handoff for unclaimed, terminal, or revoked work and for users other than the assigned bot, including managers. Refresh before preparing and before further operations; a copied prompt is a snapshot and cannot be revoked remotely. Only the captured command authorizes business work. A ChatGPT session needs an authenticated connector to use Odoo executor tools automatically, or an available browser operator. Copying instructions supplies neither connection. Record the actual outcome through the existing queue lifecycle.
This browser handoff is an optional manual alternative. Use the company-token connection above for automatic execution originating in Odoo.
Queue workflow
As an authorized requester, post a new text message in the configured direct Discuss conversation. Every eligible message creates a Pending command, so reserve the authorized conversation for commands. There is no implicit distinction between a request, acknowledgment, and conversational reply.
As the bot user, open PMIS AI Browser Operator → Command Queue and refresh before choosing work. The kanban groups commands by state; switch to the list for tabular inspection. Active Work includes claimed commands so they stay visible when returning from Discuss or a business operation. Use Pending, In Progress, or Assigned to Me to narrow the list. Remove Active Work to inspect terminal history.
Open the command and check its captured text and provenance. Select Claim / Start to revalidate current authority and move the command to In Progress.
Execute through supported executor tools or the normal Odoo UI as the bot. Use Open Originating Chat to open Discuss in another tab, reply as the bot, and return to the command. Reference the source message ID in status replies. Replies from this bot do not match this authorization's requester identity. Keep ordinary requester conversation outside the authorized chat. Attachments and linked record content do not carry command authority. Navigation verifies normal bot access and the original two-participant chat membership; it remains available after revocation or completion when that conversation is still valid. It never adds members or grants managers access to private chat history.
Save progress and the actual outcome under Bot Progress / Outcome. This evidence is audited and never automatically sent to Discuss. Select Mark Done for reported completion or Mark Failed when started work cannot be completed. Use Reject to decline pending work without executing it. Cancel with Reason stops pending or in-progress queue work and requires a reason in its dialog. Save final bot notes before the terminal transition. Terminal commands cannot be restarted or annotated through supported writes.
Managers supervise the same queue. Use Administrative Note for observations or Cancel with Reason to stop active work. Review Audit for event type, state, actor, time, cancellation reason, and bot evidence. Administrative text is neither command authority nor an operational result.
The queue warns when current provenance becomes invalid. Revocation, changed membership, inactive bot/requester users, removal of the bot's operator access, or an edited or deleted source message blocks starting work. The queue gives the current reason; the form warns to stop further work when claimed work is revoked. Re-enabling an unchanged valid authorization can permit a pending command again. In-progress work can still be annotated and marked failed, done, or cancelled to record what happened after revocation. Reporting an outcome does not authorize further business operations. An inactive user or one without operator access cannot use the lifecycle; a manager can still administratively cancel its work.
Explicit same-state writes, including repeated Start, are rejected. Unchanged result notes and empty writes create no extra audit events. Multi-record updates validate all commands before changing any; lifecycle changes and their events succeed or roll back together.
The external operator must refresh and honor revocation before further work. Odoo cannot interrupt or enforce the operator's behavior after work has started. Eligibility is checked in the claim transaction's database snapshot; a revocation committed concurrently or later is observed on refresh. Cancellation and lifecycle updates serialize on the command row. If cancellation wins, later completion or result edits fail; if completion wins, cancellation fails because history is frozen. Neither order proves whether a separate browser operation already happened.
Only the immutable Command text supplies business instructions. Bot results, administrative notes, configuration notes, attachments, chatter, linked business records, and encountered page content are evidence or context and cannot expand it. Manager-configured operating guidance supplements execution policy without expanding command authority. Discuss authorization never elevates the bot's business groups, record rules, or allowed companies.
Data model notes
pmis.ai.browser.bot associates a configuration with an existing Odoo user.
pmis.ai.command.authorization associates a bot, requester, and direct chat and controls whether that combination can capture new commands.
pmis.ai.command is the captured command authority record. It retains the source message ID, HTML and plain-text snapshots, requester, author partner, bot, channel, authorization, and capture timestamp. Source deletion clears the live message relation while retaining the original message ID and snapshots. command_digest is the lowercase hexadecimal SHA-256 of the UTF-8 encoded command_text: Odoo's html2plaintext conversion without link references, followed by trimming leading and trailing whitespace. No further whitespace or Unicode normalization is performed. Equal normalized instructions have equal digests; command record IDs and provenance distinguish submissions.
pmis.ai.command.event stores immutable audit entries, explicitly separating command capture, bot progress/outcomes, bot cancellation, administrative cancellation, and administrative notes. Commands and audit events cannot be deleted through the module.
pmis.ai.command.intervention is a temporary reason/note dialog. Its submit action rechecks the real user's authority and the command's current state.
The Discuss post hook preserves Odoo's posting user, including the normal web controller's sudo environment. A private service validates identity and the authorization before narrowly elevating access to create the command and audit record. Public command creation is blocked; there are no caller-supplied trust flags or public capture methods. Business actions receive no elevated access.
An eligible post and its command/audit capture share the posting transaction. Capture errors propagate instead of accepting a message without its command. Ineligible messages bypass command creation. Duplicate capture returns the existing command; a concurrent insert invisible to the current PostgreSQL snapshot requests a transaction retry instead of losing the command or audit.
Partial unique database indexes prevent duplicate active bot configurations for one user and duplicate active authorization combinations. A unique bot-user and source-message constraint prevents duplicate command capture.
Lifecycle writes check access, flush the ORM recordset, and lock command rows in ID order with PostgreSQL FOR UPDATE NOWAIT before validating their state. The ORM cache is invalidated after locking. Odoo's normal RPC transaction retry handles lock and serialization conflicts under its repeatable-read isolation; after the winner commits, a repeated start fails the state check. A rolled-back claim leaves the command pending. No business work belongs inside this claim transaction: the external operator waits for successful Claim / Start before acting.
The stored digest is computed from captured text, including on terminal commands and commands whose source was deleted. Computing it does not recapture messages or create lifecycle events. It identifies instruction text but does not provide tamper-proof evidence against database administrators or trusted server-side code.
Recorded By identifies the last result-note author using bot-update and Legacy Capture / Update events, ignoring events that merely repeat the note. The form warns when assigned-bot authorship cannot be established. Only the assigned bot can edit its result on active commands; terminal records remain frozen.
Cancellation uses action_cancel(reason) or its reason dialog. Direct write({'state': 'cancelled'}) raises an error. Administrative observations use action_administrative_note(note) and never update result_note. The current module loads the intervention dialog and typed audit events with its normal models and views.
Known limitations
Existing messages are not scanned retroactively. Notifications, email, bot replies, other conversations, chatter on other models, and direct mail.message.create() calls do not create commands.
Attachments, images alone, link destinations, and business record content are not extracted as commands. A message must contain nonempty plain text.
Completion records the operator's reported outcome. Executor receipts record accepted supported actions; the module does not infer whether those actions completely satisfy the natural-language instruction.
Revocation prevents a new start but cannot stop an external operator already working. The operator remains responsible for checking current authority.
Manual claiming is per command and bot user. Connected AI runs additionally have a fenced claim identifier, bounded runtime, heartbeat, and private retry journal. Different authorized commands may still run independently.
The module has no automated audit retention or external command ingestion. Every eligible message in an authorized conversation is captured. Capture grants no company access and does not impersonate the requester.
Administrative cancellation records a stop request and terminal queue state; it neither interrupts the browser nor rolls back business changes already made. Later corrections need a separate operational record; terminal audit history cannot be rewritten here.
Development
Model and wizard Python filenames follow their full technical model names, such as models/pmis_ai_browser_bot.py. Separate extensions use descriptive suffixes. Each Python class has its own source file, and focused test filenames mirror their source modules. Model-specific XML files use the same prefix, including views/pmis_ai_browser_bot_views.xml and data/pmis_ai_skill_data.xml. Command intervention and executor wizard views have separate model-specific files.
The deterministic tests in tests/ use synthetic provider responses and exercise ordinary-user Odoo execution. They do not sign in to a real ChatGPT account or make live inference requests.
Use the repository's scoped test runners with an authorized disposable database whose name starts with test_. Concurrency tests commit synthetic fixtures, so production databases must never be used. tests/odoo_dependencies.txt declares CRM, Sales, and Website as test-only dependencies. Both standard runners install them automatically before pytest, including PyCharm runs using the single-addon runner. No manual preparation or preserved database is required. These apps remain optional in production; do not install modules inside test fixtures.
Use run_pytest_addon.sh for focused tests and run_pytest_repo.sh --addons <addon-path> for coverage. When reusing a prepared database, pass --keep-db only if it needs to remain available for inspection. For complete statement and branch coverage, run the scoped coverage gate with --cov-branch and --cov-fail-under=100. The declared test apps must be available on the configured Odoo addons path.
Remove only the task-owned disposable database when finished. Static checks use the repository's pyproject.toml and the nonwriting run_lint_addon.sh --addon <addon-path> --check command.
TODO
Extend reviewed executor operations before adding skills for quotation sending, invoicing, delivery processing, order cancellation, or confirmed-order edits.
Add direct in-Odoo ChatGPT authorization when a supported hosted plan-use authentication contract is available for this integration. The company-token connection currently requires manual token creation in the workspace.
Bug Tracker
Bugs are tracked on PMISuite Repository Issues. Before opening a new issue, check whether it has already been reported. Include the module and Odoo versions, steps to reproduce, and expected and actual results. Use synthetic examples and redact sensitive information.
Credits
Contributors
Matjaž Mozetič
Maintainers
Current maintainer:
Luxim is an independent R&D and deployment company focused on solving complex problems in the Odoo ecosystem.
Luxim is an active member of OCA (Odoo Community Association).






