Skip to content

Product Borrow Documentation

Overview

The Product Borrow module (product.borrow) manages the lending of inventory items to employees or projects. It provides a complete workflow for borrowing requests, item issuance, return tracking, and overdue monitoring. This module is essential for organizations that lend equipment, tools, or materials to employees.


Model Information

Model Name: product.borrow
Display Name: Borrow Request
Name Field: number
Key Fields: N/A

Features

  • ✅ Automated sequence numbering
  • ✅ State workflow management
  • ✅ Overdue tracking
  • ✅ Return tracking
  • ✅ Integration with stock movements
  • ✅ Document and comment attachments

State Workflow

draft → approved → done
       voided
State Description
draft Initial state, request being prepared
approved Request approved, ready for issuance
done All items issued and returned, completed
voided Request cancelled/voided

Key Fields Reference

Header Fields

Field Type Required Description
number Char Auto-generated borrow request number
date Date Request date
employee_id Many2One Employee borrowing items (hr.employee)
project_id Many2One Associated project (project)
borrow_for Char Purpose/reason for borrowing
due_date Date Expected return date
notes Text Additional notes or comments
state Selection Current workflow state

Computed Fields

Field Type Description
is_overdue Boolean True if past due date and state is "approved"
is_return_item Boolean True if all borrowed items fully returned
pickings Many2Many Associated stock pickings (computed from stock_moves)

Relationship Fields

Field Type Description
lines One2Many Borrowed item lines (product.borrow.line)
stock_moves One2Many Stock movements for borrow/return
comments One2Many Comments and notes (message)
documents One2Many Attached documents (document)

API Methods

1. Create Borrow Request

Method: create(vals, context)

Creates a new borrow request with auto-generated number.

Parameters:

vals = {
    "date": "2025-10-27",                 # Required: Request date
    "employee_id": 123,                   # Required: Employee ID
    "borrow_for": "Field work equipment", # Required: Purpose
    "due_date": "2025-11-10",            # Required: Return date
    "project_id": 456,                    # Optional: Project
    "notes": "Handle with care",          # Optional: Notes
    "lines": [                            # Optional: Items
        ("create", {
            "product_id": 789,
            "qty": 2,
            "uom_id": 1,
            "lot_id": 101
        })
    ]
}

Returns: int - New record ID

Example:

# Create borrow request for tools
borrow_id = get_model("product.borrow").create({
    "date": "2025-10-27",
    "employee_id": employee_id,
    "borrow_for": "Construction site tools",
    "due_date": "2025-11-15",
    "project_id": project_id,
    "lines": [
        ("create", {
            "product_id": drill_id,
            "qty": 1,
            "uom_id": unit_id
        }),
        ("create", {
            "product_id": hammer_id,
            "qty": 2,
            "uom_id": unit_id
        })
    ]
})


2. Approve Borrow Request

Method: approve(ids, context)

Moves request from draft to approved state.

Example:

get_model("product.borrow").approve([borrow_id])


3. Complete Borrow Request

Method: set_done(ids, context)

Marks request as completed when all items returned.

Example:

get_model("product.borrow").set_done([borrow_id])


4. Void Borrow Request

Method: void(ids, context)

Cancels/voids the borrow request.

Example:

get_model("product.borrow").void([borrow_id])


5. Copy to Goods Issue Picking

Method: copy_to_picking(ids, context)

Creates a goods issue (outbound) picking for borrowing items.

Returns: Dictionary with navigation and flash message

Example:

result = get_model("product.borrow").copy_to_picking([borrow_id])
# Returns picking_id and navigation info


6. Copy to Goods Receipt Picking

Method: copy_to_pick_in(ids, context)

Creates a goods receipt (inbound) picking for returning items.

Example:

result = get_model("product.borrow").copy_to_pick_in([borrow_id])


7. Delete Borrow Request

Method: delete(ids, context)

Deletes borrow request with validation.

Validation: - Can only delete requests in draft state - Cannot delete if stock moves exist


Computed Fields Functions

get_overdue(ids, context)

Returns True if due date is past and state is "approved".

get_return_item(ids, context)

Returns True if all borrowed items have been fully returned.

get_pickings(ids, context)

Returns list of unique picking IDs from stock moves.


Configuration Settings

Required Settings

Setting Location Description
product_borrow_journal_id settings (ID:1) Journal for borrow transactions

The journal must have: - location_from_id: Source location (warehouse) - location_to_id: Destination location (employee/temp)

Setup Example:

settings = get_model("settings").browse(1)
settings.write({
    "product_borrow_journal_id": journal_id
})

journal = get_model("stock.journal").browse(journal_id)
journal.write({
    "location_from_id": warehouse_loc_id,
    "location_to_id": temp_loc_id
})


Model Relationship Description
product.borrow.line One2Many Borrow line items
hr.employee Many2One Employee borrowing items
project Many2One Associated project
stock.picking Related Goods issue/receipt pickings
stock.move One2Many Stock movements
message One2Many Comments
document One2Many Attachments

Common Use Cases

Use Case 1: Complete Borrow and Return Workflow

# 1. Create borrow request
borrow_id = get_model("product.borrow").create({
    "date": "2025-10-27",
    "employee_id": employee_id,
    "borrow_for": "Field equipment",
    "due_date": "2025-11-10",
    "lines": [
        ("create", {
            "product_id": laptop_id,
            "qty": 1,
            "uom_id": unit_id
        })
    ]
})

# 2. Approve request
get_model("product.borrow").approve([borrow_id])

# 3. Issue items
result = get_model("product.borrow").copy_to_picking([borrow_id])
pick = get_model("stock.picking").browse(result["picking_id"])
pick.set_done()

# 4. Return items
result = get_model("product.borrow").copy_to_pick_in([borrow_id])
return_pick = get_model("stock.picking").browse(result["picking_id"])
return_pick.set_done()

# 5. Complete borrow
get_model("product.borrow").set_done([borrow_id])

Use Case 2: Track Overdue Borrows

import time

current_date = time.strftime("%Y-%m-%d")

# Get approved borrows past due date
overdue_ids = get_model("product.borrow").search([
    ["state", "=", "approved"],
    ["due_date", "<", current_date]
])

for borrow in get_model("product.borrow").browse(overdue_ids):
    print(f"Overdue: {borrow.number}")
    print(f"  Employee: {borrow.employee_id.name}")
    print(f"  Due: {borrow.due_date}")

    for line in borrow.lines:
        outstanding = line.issued_qty - line.returned_qty
        if outstanding > 0:
            print(f"    - {line.product_id.name}: {outstanding} units")

Best Practices

1. Set Realistic Due Dates

from datetime import datetime, timedelta

due_date = (datetime.now() + timedelta(days=14)).strftime("%Y-%m-%d")

borrow_vals = {
    "due_date": due_date,  # ✅ 2 weeks from now
}

2. Track Serial Numbers for High-Value Items

borrow_lines = [
    ("create", {
        "product_id": laptop_id,
        "qty": 1,
        "uom_id": unit_id,
        "lot_id": serial_number_id  # ✅ Track exact unit
    })
]

3. Use Projects for Better Tracking

borrow_vals = {
    "employee_id": employee_id,
    "project_id": project_id,  # ✅ Track by project
    "borrow_for": "Project XYZ equipment",
}

Troubleshooting

"Missing borrow request journal in Inventory Setting"

Cause: product_borrow_journal_id not configured
Solution: Configure journal in settings

"Missing 'Location From' for journal"

Cause: Journal doesn't have source location
Solution: Set location_from_id on journal

"Can not delete borrow request"

Cause: Wrong state or stock moves exist
Solution: Only delete draft requests without moves


Version History

Last Updated: 2025-10-27
Model Version: product_borrow.py
Framework: Netforce


Additional Resources

  • Product Borrow Line Documentation: product.borrow.line
  • HR Employee Documentation: hr.employee
  • Stock Picking Documentation: stock.picking

This documentation is generated for developer onboarding and reference purposes.