Skip to main content

Item Request — Management Sponsorship Workflow

Blu Coffee gives out machines, beans, and consumables for free — coffee stations at hotels, branded espresso bars at sales conferences, sample kits for key clients. The Item Request module captures that work as an approvable, traceable inventory movement:

  • The items are removed from stock through a scrap-location move so cost lands on the books with the requestor's name on the journal entry.
  • The head of the requesting department approves remotely via Viber — they tap a button on their phone, land on a mobile-friendly review page, and decide right there. They don't need an Odoo login.
  • A signed ISO document must be attached before the inventory move is actually executed, giving Accounting a paper trail.

In short: it's inventory-scrapping mechanically, sponsorship-tracking commercially, Viber-approved operationally.

Where the Viber stack comes from

The Viber send reuses the API key and sub-account already configured for Viber marketing campaigns. If blu_8x8.blu_8x8_api_key or the messaging sub-account ID is empty in Settings → 8x8, the submit hook silently skips Viber (it still files the email).

State machine

Cancel is non-destructive at every stage except Done. Once a request is Done, the stock moves have already happened — the order stays Done and only a separate stock-correction can undo it.

End-to-end flow

Configuration — Departments

The approver's contact details live on the department. Open Inventory → Configuration → Department to manage the list.

Department list

A department record has four fields that matter:

FieldPurpose
NameDepartment label (e.g. MARKETING & TRAINING DEPARTMENT). Required, unique.
Department HeadDisplay name — used to personalise the Viber message ("Hi Juan…").
Department Head EmailReceives the approval email with the review-page button. If empty, no email is sent.
Viber NumberWhere the Viber approval request lands. PH format accepted (09xx… or +639xx…). If empty or unparseable, the submit hook just skips Viber and logs a warning.

Department form

One Viber number, multiple approvers

The Viber field is a single number — it's the phone that gets the "Review IR-####" button. Use a department-head phone or a shared sponsorship-approvals number. If you need a second pair of eyes, the approver can take a screenshot of the Viber message and forward it — the review URL is a public token-protected link, so anyone who has it can act on the request.

Creating a request

Inventory → Operations → Adjustments → Item Request → New lands you on an empty draft.

Empty Item Request form

SectionFields
Request DetailRequested by (partner picker — the person on whose name the cost will land), Position, Date Requested (defaults to today), Date Needed
LocationsSource Location (internal-usage stock with blu_active=True), Destination Location (must be a scrap-type location — typically Virtual Locations/Scrap), Purpose (required free-text), Department (required — picks the approver)
LinesProduct, UoM, Quantity. Optional per-line Source Location, Owner, Package. UoM must be in the same category as the product's default UoM.

A filled draft looks like this — note the Submit button in the header and the Draft badge on the right:

Filled draft Item Request

Click Submit. Two things happen, in parallel:

  1. The status badge moves from DraftTo Approve.
  2. The chatter logs a confirmation line: "Viber approval request sent to Jun Salinga (+639982123652)" — that's the proof your Viber payload was posted.

Submitted Item Request — state To Approve, Viber log in chatter

The approver's phone

The Viber arrives as a buttoned chat message from the Blu Coffee channel — personalised greeting, request summary, line items, a link to the PDF, and a single Review IR-#### button:

Viber approval message
1. Viber message arrives
Mobile review page
2. Tap Review IR-#### → mobile review card
Item Request PDF on phone
3. Tap View Full PDF → print-ready document

The chat-message text itself includes a plain-text View PDF: link — that's the same URL the View Full PDF button on the review card opens, and it works even if the recipient prefers to read the PDF first before opening the review card.

The review card gives the approver three actions:

ButtonEffect on the Item RequestNotifications fired
Approvestate → Approved. Optional comment saved as approval_comment and posted to chatter.None (the chatter entry is the audit trail).
Disapprovestate → Cancelled. Reason saved as approval_comment and posted to chatter.None.
Send Note Onlystate goes back to Draft. Comment is required. The note is sent to the creator via both Viber and email so they know what to fix.Viber to creator's mobile + email to creator's address.
Public URLs but token-gated

Both /item-request/<id>/review and /item-request/pdf/<id> are auth='public' (no Odoo login required) and require the per-record access_token (UUID4 hex) as a query parameter. Tokens are generated on create and never regenerated — so anyone holding the URL can read or act. Don't forward it outside the approval chain.

After the approver acts, the public page renders a confirmation card (green tick for Approve/Note Sent, red for Disapprove) and the IR's state in Odoo is already updated. The approver doesn't need to do anything else.

States by example

For reference, here's what each state looks like in the Odoo backend.

Approved — ready for the final inventory move

Approved Item Request

Done — inventory moved, journal entry posted

Done Item Request

Cancelled — either disapproved by the head, or manually cancelled

Cancelled Item Request

Confirming & moving the inventory

Once the request is Approved, the creator (or an Inventory user with access) needs to do two things:

  1. Attach the signed ISO to the request — paperclip icon → Upload → PDF, JPG, or PNG. This is enforced by action_confirm(); without an attachment in those mimetypes you get an error telling you to attach the file first.
  2. Click Confirm & Scrap. This iterates every line and:
    • Creates a stock.scrap (linked back via batch_order_id and order_line_id)
    • Validates it immediately (stock leaves the source location, lands in the scrap destination)
    • Writes partner_id = requested_by_id and ref = "IR-####/<product name>" onto the resulting journal entry and every journal item, so the cost is attributable in P&L reports

The IR's state flips to Done. The smart button at the top — Scrap Orders — opens the list of underlying stock.scrap records for traceability.

Standard scrap menu hides these

The regular Inventory → Operations → Scrap Orders menu is patched to filter out is_item_request=True so sponsorship moves don't pollute the day-to-day scrap list. To see them, drill in from the Item Request form via the smart button.

Item Request list — search & reporting

The list view supports the standard state filters plus a few useful groupings:

Item Request list

Pivot + Graph views are pre-declared on the action, so the same data feeds analytics out of the box — useful for tracking sponsorship spend per department or per requestor over time.

Reference — code & data map

ConcernFile
Main model (header + state machine + Viber/email hooks)common/item_request/models/item_request.py
Line modelsame file (StockScrapOrderLine)
Department lookupcommon/item_request/models/department.py
stock.scrap extension (batch_order_id, is_item_request)common/item_request/models/stock_scrap.py
Public controllers (review page, PDF, approve/reject/note)common/item_request/controllers/main.py
Backend views (form, list, search)common/item_request/views/item_request_views.xml
Department viewscommon/item_request/views/department_views.xml
Email templatescommon/item_request/data/mail_template.xml
QWeb PDF reportcommon/item_request/report/item_request_report.xml
Sequence (IR-YYYY-#####)common/item_request/views/item_request_views.xml

Public URLs

URLMethodAuthPurpose
/item-request/<id>/review?token=<access_token>GETpublicRenders the mobile review card
/item-request/<id>/approve?token=<access_token>POSTpublicApproves (state → Approved). Body: optional comment.
/item-request/<id>/reject?token=<access_token>POSTpublicDisapproves (state → Cancelled). Body: optional comment.
/item-request/<id>/note?token=<access_token>POSTpublicSends note + flips state back to Draft. Body: comment required.
/item-request/pdf/<id>?token=<access_token>GETpublicRenders the QWeb PDF inline

Settings touchpoints

WhereWhy
Settings → 8x8 → 8x8 API Key, Messaging App Sub-account IDUsed by _send_viber_approval() and _send_viber_note_to_requestor(). Empty → Viber silently skipped.
Settings → System Parameters → web.base.urlEmbedded in the review/PDF URLs sent to the approver. Make sure this is the public host, not localhost:8017.
Inventory → Configuration → DepartmentDepartment head name, email, Viber number per department