Skip to content

Sales Profit Details Report Documentation

Overview

The Sales Profit Details Report module (report.sale.profit.details) provides line-item drill-down analysis for a specific sales order, showing cost, pricing, and profit margins for each product/service line. This is the detail companion to report.sale.profit.


Model Information

Model Name: report.sale.profit.details Display Name: Sales Profit Details Report Type: Transient Report Model (_transient = True)

Features

  • Line-by-line profit breakdown for a single order
  • Product description and quantities
  • Unit price and total amount per line
  • Cost price and total cost per line
  • Links to parent profit summary report

Key Fields Reference

Report Parameters

Field Type Required Description
sale_id Many2One Yes Sales order to analyze (required for detail view)

Output Fields

Field Description
sequence Line sequence/description
description Product/service description
qty Quantity ordered
uom_name Unit of measure
unit_price Unit selling price
amount Line total (unit_price * qty)
cost_price Unit cost price
cost_amount Line total cost (cost_price * qty)

API Methods

1. Generate Detail Report

Method: get_report_data(ids, context)

Generates line-item profit details for a specific order.

Parameters:

ids = [report_id]  # Report configuration ID with sale_id set

context = {}       # Optional context

Returns: dict - Report data:

{
    "company_name": "ABC Company",
    "order_number": "SO-2024-001",
    "lines": [
        {
            "sequence": "Product XYZ",
            "description": "Product XYZ - Premium Quality",
            "qty": 10,
            "uom_name": "Unit",
            "unit_price": 150.00,
            "amount": 1500.00,
            "cost_price": 100.00,
            "cost_amount": 1000.00
        }
    ]
}

Example:

# Generate detail report for specific order
sale_order_id = 123

detail_report_id = get_model("report.sale.profit.details").create({
    "sale_id": sale_order_id
})

data = get_model("report.sale.profit.details").get_report_data([detail_report_id])

print(f"Profit Details for Order {data['order_number']}:")
for line in data["lines"]:
    line_profit = line["amount"] - line.get("cost_amount", 0)
    line_margin = (line_profit / line["amount"]) * 100 if line["amount"] else 0
    print(f"  {line['description']}: ${line['amount']:,.2f} - Margin {line_margin:.1f}%")


Model Relationship Description
sale.order Required Parent Sales order being analyzed
sale.order.line Data Source Order lines with pricing and costs
report.sale.profit Parent Report Summary-level profit report

Common Use Cases

Use Case 1: Line-Item Profitability Review

# Analyze which products in an order are most/least profitable

sale_order_id = 456

report_id = get_model("report.sale.profit.details").create({
    "sale_id": sale_order_id
})

data = get_model("report.sale.profit.details").get_report_data([report_id])

# Calculate margin for each line
line_analysis = []
for line in data["lines"]:
    if line.get("amount") and line.get("cost_amount") is not None:
        profit = line["amount"] - line["cost_amount"]
        margin = (profit / line["amount"]) * 100 if line["amount"] else 0
        line_analysis.append({
            "product": line["description"],
            "qty": line["qty"],
            "revenue": line["amount"],
            "cost": line["cost_amount"],
            "profit": profit,
            "margin": margin
        })

# Sort by margin
line_analysis.sort(key=lambda x: x["margin"])

print("Line Items by Margin (Low to High):")
for item in line_analysis:
    print(f"{item['product']}: {item['margin']:.1f}% margin (Profit: ${item['profit']:,.2f})")

Use Case 2: Integrated Summary-to-Detail Flow

# Start with summary, drill down on low-margin orders

# 1. Generate summary
summary_id = get_model("report.sale.profit").create({
    "date_from": "2024-01-01",
    "date_to": "2024-01-31"
})

summary_data = get_model("report.sale.profit").get_report_data([summary_id])

# 2. Find orders with margins < 20%
low_margin_orders = [
    line for line in summary_data["lines"]
    if line.get("act_profit_percent", 0) < 20
]

print(f"Found {len(low_margin_orders)} orders with margins < 20%\n")

# 3. Drill down into each
for order in low_margin_orders:
    detail_id = get_model("report.sale.profit.details").create({
        "sale_id": order["id"]
    })

    detail_data = get_model("report.sale.profit.details").get_report_data([detail_id])

    print(f"Order {order['number']} - {order['customer']}:")
    print(f"  Overall Margin: {order.get('act_profit_percent', 0):.1f}%")
    print("  Line Items:")

    for line in detail_data["lines"]:
        if line.get("amount"):
            line_profit = line["amount"] - line.get("cost_amount", 0)
            line_margin = (line_profit / line["amount"]) * 100
            print(f"    - {line['description']}: {line_margin:.1f}% margin")
    print()

Use Case 3: Product Pricing Review

# Review pricing vs cost across multiple orders for a product

product_name = "Widget Pro"

# Find orders containing this product
orders = get_model("sale.order").search_browse([
    ["lines.product_id.name", "=", product_name],
    ["date", ">=", "2024-01-01"]
])

product_pricing = []

for order in orders:
    detail_id = get_model("report.sale.profit.details").create({
        "sale_id": order.id
    })

    data = get_model("report.sale.profit.details").get_report_data([detail_id])

    # Find the product line
    product_line = next((l for l in data["lines"] if product_name in l.get("description", "")), None)

    if product_line and product_line.get("amount"):
        margin = ((product_line["amount"] - product_line.get("cost_amount", 0)) / product_line["amount"]) * 100
        product_pricing.append({
            "order": order.number,
            "customer": order.contact_id.name,
            "qty": product_line["qty"],
            "unit_price": product_line["unit_price"],
            "cost_price": product_line.get("cost_price", 0),
            "margin": margin
        })

print(f"Pricing Analysis for {product_name}:")
for pricing in product_pricing:
    print(f"{pricing['order']} - {pricing['customer']}:")
    print(f"  Price: ${pricing['unit_price']:,.2f}, Cost: ${pricing['cost_price']:,.2f}, Margin: {pricing['margin']:.1f}%")

Performance Tips

1. Single Order Focus

  • This report is designed for single order analysis
  • Don't iterate through all orders in a loop (use summary report instead)
  • Use summary report to identify orders worth drilling into

2. Efficient Workflow

# Good: Selective drill-down
summary_report -> identify problem orders -> detail report for each

# Bad: Drill into every order
for order in all_orders:  # Don't do this
    generate_detail_report(order.id)

Troubleshooting

"No sale_id provided"

Cause: Detail report requires a specific sale order ID Solution: - Always provide sale_id parameter when creating report - Get sale_id from summary report or order search

"Cost amounts missing"

Cause: Order lines don't have cost_price populated Solution: - Ensure products have cost prices configured - Check if cost calculation is set up correctly - Cost may be unavailable for service items


Version History

Last Updated: 2026-01-05 Model Version: report_sale_profit_details.py (47 lines) Framework: Netforce


Additional Resources

  • Summary Report Documentation: report.sale.profit
  • Sales Order Documentation: sale.order

This documentation is generated for developer onboarding and reference purposes.