Skip to main content
Billing & Finance

Sales (Proforma Lines and Credits)

Manage proforma sales lines with automatic price calculation from catalog items, including credit applications.

Auth required: Yes (auth:api) for protected endpoints.


Model Properties

Sale (Invoiced Line Item)

Sale lines are created automatically by the billing engine when invoices are generated. They are read-only.

Property Type Description
id integer Unique identifier
invoice_id integer FK to invoices
customer_file_id integer FK to customer_files
line_key string Links this sale to the source billing item (initial or recurring)
item_id integer FK to items (catalog item)
family_id integer FK to families (product family at time of billing)
sale_type string Type of sale: initial, recurring, or consumptions
description string Item description at time of billing
phone_line_description string Phone line description (for consumption lines)
label string Custom line label
quantity decimal Billed quantity
selling_price_without_tax_before_discount decimal Unit price before discount, excl. tax
tax_before_discount decimal Unit tax before discount
selling_price_with_tax_before_discount decimal Unit price before discount, incl. tax
discount_rate decimal Discount rate applied
selling_price_without_tax decimal Unit price after discount, excl. tax
tax decimal Unit tax after discount
selling_price_with_tax decimal Unit price after discount, incl. tax
line_without_tax decimal Total line amount excl. tax (quantity x unit price)
line_tax decimal Total line tax amount
line_with_tax decimal Total line amount incl. tax
tax_rate decimal Applied VAT rate
created_at datetime Creation timestamp
updated_at datetime Last update timestamp

Proforma Sale Line

Proforma sale lines are the editable line items within a proforma invoice. Prices are auto-calculated from the catalog item when created.

Property Type Required Description
id integer auto Unique identifier
invoice_proforma_id integer Yes (query param) FK to invoices_proforma
item_id integer Yes* FK to items. Required if bar_code not provided
bar_code string Yes* Item barcode. Alternative to item_id
quantity numeric Yes Quantity
discount_rate decimal No Discount rate (e.g. 0.1 = 10%). Triggers price recalculation on update
selling_price_without_tax decimal auto Selling price per unit, excl. tax. Auto-calculated from item price list
buying_price_without_tax decimal auto Buying price per unit, excl. tax. Auto-calculated
line_without_tax decimal auto Total line amount excl. tax
created_at datetime auto Creation timestamp
updated_at datetime auto Last update timestamp

Proforma Sales Lines

Base URL: /api/v1/sales-proforma

Sales lines are the individual line items within a proforma invoice. Prices are automatically calculated from the catalog item.

GET /v1/sales-proforma

List proforma sales for a specific proforma invoice.

Query parameters:

Parameter Type Required Description
invoice_proforma_id integer Yes Filter by proforma invoice ID

Response 200: Array of proforma sale objects.

Examples:

curl -X GET "https://your-instance.bluerocktel.net/api/v1/sales-proforma?invoice_proforma_id=15" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
import requests

response = requests.get(
    "https://your-instance.bluerocktel.net/api/v1/sales-proforma",
    params={"invoice_proforma_id": 15},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"}
)
sales = response.json()
$response = Http::withToken('YOUR_API_TOKEN')
    ->get('https://your-instance.bluerocktel.net/api/v1/sales-proforma', [
        'invoice_proforma_id' => 15,
    ]);

$sales = $response->json();
const response = await fetch(
  "https://your-instance.bluerocktel.net/api/v1/sales-proforma?invoice_proforma_id=15",
  {
    headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Accept": "application/json"
    }
  }
);
const sales = await response.json();

POST /v1/sales-proforma

Create a new proforma sale line. Prices are auto-calculated: buying price, selling price, taxes, discounts. The item can be identified by item_id or bar_code.

Query parameters:

Parameter Type Required Description
invoice_proforma_id integer Yes Proforma invoice to add the line to

Body (JSON): Validated via sale_proforma::attributes('common', 'store'):

Field Type Description
item_id integer Catalog item ID (alternatively: bar_code)
bar_code string Item barcode (alternative to item_id)
quantity numeric Quantity
discount_rate numeric Discount percentage
... ... Other proforma sale fields

Prices are computed from the item's price list adjusted for customer VAT and provided discount.

Response 201: Created proforma sale object. Response 422: Invalid item or validation error.

Examples:

curl -X POST "https://your-instance.bluerocktel.net/api/v1/sales-proforma?invoice_proforma_id=15" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": 100,
    "quantity": 2,
    "discount_rate": 10
  }'
import requests

response = requests.post(
    "https://your-instance.bluerocktel.net/api/v1/sales-proforma",
    params={"invoice_proforma_id": 15},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"},
    json={
        "item_id": 100,
        "quantity": 2,
        "discount_rate": 10
    }
)
sale = response.json()
$response = Http::withToken('YOUR_API_TOKEN')
    ->post('https://your-instance.bluerocktel.net/api/v1/sales-proforma?invoice_proforma_id=15', [
        'item_id' => 100,
        'quantity' => 2,
        'discount_rate' => 10,
    ]);

$sale = $response->json();
const response = await fetch(
  "https://your-instance.bluerocktel.net/api/v1/sales-proforma?invoice_proforma_id=15",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      item_id: 100,
      quantity: 2,
      discount_rate: 10
    })
  }
);
const sale = await response.json();

GET /v1/sales-proforma/{id}

Get a single proforma sale line.

URL parameters:

Parameter Type Description
id integer Proforma sale ID

Response 200: Proforma sale object. Response 404: Not found.


PUT /v1/sales-proforma/{id}

Update a proforma sale line. All pricing fields are recalculated.

URL parameters:

Parameter Type Description
id integer Proforma sale ID

Body (JSON): Validated via sale_proforma::attributes('common').

Response 201: Updated proforma sale object. Response 404: Not found.

Examples:

curl -X PUT "https://your-instance.bluerocktel.net/api/v1/sales-proforma/88" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"quantity": 5, "discount_rate": 15}'
import requests

response = requests.put(
    "https://your-instance.bluerocktel.net/api/v1/sales-proforma/88",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"},
    json={"quantity": 5, "discount_rate": 15}
)
sale = response.json()
$response = Http::withToken('YOUR_API_TOKEN')
    ->put('https://your-instance.bluerocktel.net/api/v1/sales-proforma/88', [
        'quantity' => 5,
        'discount_rate' => 15,
    ]);

$sale = $response->json();
const response = await fetch(
  "https://your-instance.bluerocktel.net/api/v1/sales-proforma/88",
  {
    method: "PUT",
    headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ quantity: 5, discount_rate: 15 })
  }
);
const sale = await response.json();

DELETE /v1/sales-proforma/{id}

Delete a proforma sale line.

URL parameters:

Parameter Type Description
id integer Proforma sale ID

Response 200: Success message. Response 404: Not found.


Sale Credit

Base URL: /api/v1/

POST /v1/sales/credit

Apply a credit to a sale. This endpoint does NOT require authentication (auth:api middleware is NOT applied).

Body (JSON):

Details depend on the ApiSaleController@credit implementation.

Response: Credit result.

Examples:

curl -X POST "https://your-instance.bluerocktel.net/api/v1/sales/credit" \
  -H "Content-Type: application/json" \
  -d '{"sale_id": 200, "amount": 50.00}'
import requests

response = requests.post(
    "https://your-instance.bluerocktel.net/api/v1/sales/credit",
    json={"sale_id": 200, "amount": 50.00}
)
result = response.json()
$response = Http::post('https://your-instance.bluerocktel.net/api/v1/sales/credit', [
    'sale_id' => 200,
    'amount' => 50.00,
]);

$result = $response->json();
const response = await fetch(
  "https://your-instance.bluerocktel.net/api/v1/sales/credit",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sale_id: 200, amount: 50.00 })
  }
);
const result = await response.json();