github mlebreuil/netbox-contract v2.5.0

2 hours ago

Warning

This version requires NetBox 4.6.0 or later. Read the Breaking Changes below before upgrading: the upgrade converts the contract costs and invoice templates into contract lines, and changes how invoices are created and locked.

Breaking Changes

  • A new invoice can no longer be linked to more than one contract. Existing invoices linked to several contracts stay as they are and can be edited, but no contract can be added to them. These rules also apply to bulk edits of invoices, whose Template field is offered only when show_deprecated_fields is True. (#278)
  • A new invoice must have the currency of its contract, and cannot be created for a non-billable contract. (#278)
  • Creating an invoice (web interface or POST invoices/) now generates its invoice lines from the contract lines, and is refused when the invoice amount is lower than their total. Invoice lines are not generated when an invoice is edited or imported. (#278)
  • The copy of invoice template lines onto a new invoice is removed. Invoice templates are no longer used to pre-fill invoices; the pre-fill uses the contract lines instead of mrc and yrc. (#278)
  • New invoices are Draft by default (previously Posted), in the web interface and the REST API; imports still set the status given in the file. (#278)
  • Posted invoices are locked: their amount, currency, period and contracts cannot change, lines cannot be added or deleted, and the unit, unit price, quantity and amount of their lines cannot change. Set an invoice back to Draft to correct it. (#278)
  • The amount of every invoice line is quantity x unit price and can no longer be typed, as in most ERPs; the unit price is required and the quantity defaults to 1. An import or API call that gives only an amount still works: the amount becomes the unit price with quantity 1. Migration 0049 gives existing lines a unit price without changing any amount. (#278)
  • Contract lines are locked once their contract has an invoice (any status) or once an invoice line references them: a new contract must be created. Their accounting dimensions, comments and tags remain editable, and their price or quantity can be amended from a date after the last invoiced period. The billing method and months of a unit used by such lines are locked too. (#278)
  • The billable flag of a contract cannot change once the contract, one of its parents or one of its children has invoices. The currency of a contract cannot change once it has invoices or invoice lines; without invoices, its contract lines follow the new currency. Changing the currency of a contract also changes its non-billable descendants of the same currency, unless one of them has invoices. (#278)
  • A contract whose lines (or those of its child contracts) are on posted invoices can no longer be deleted. (#278)
  • The contract cost fields, new invoice templates and the invoice template section of the contract page are hidden unless show_deprecated_fields is True; templates remain reachable from the invoice list. The mandatory and hidden field settings ignore a deprecated field that is not shown (with a warning in the log) instead of failing. (#278)
  • The custom scripts create_invoice_template and create_invoice_lines are removed: they read fields that no longer exist and are superseded by the conversion. (#278)
  • API clients that passed filters to serviceproviders/, contracttype/, accountingdimension/ or contractassignment/ now get the filtered list instead of every object. (#307)
  • Amending a contract line requires the new amend permission action. The add and change contract line permissions (required since #307) are no longer enough; administrators grant the new action to the users who amend lines. This applies to the screen and to the REST action POST contract-lines/{id}/amend/. (#309)
  • The related tables of detail pages show the default columns of their lists (for example the contract lines of a contract show the contract line list columns, without the contract). Users who want other columns choose them on the list with Configure Table. (#309)
  • On the contract page, the deprecated costs (mrc, yrc, nrc, shown with show_deprecated_fields) are grouped in a Deprecated costs panel. The invoice page applies the hidden_invoice_fields setting, which it ignored until now. (#309)
  • Contract type descriptions are limited to 200 characters, as on core objects: a longer description is refused (form, import, REST API). On upgrade, every contract type gets a slug derived from its name, made unique with -2, -3, ... when needed, and a longer description is shortened at a word boundary (ending with "…") with its full text moved to the new comments; the migration prints every slug it made unique and every description it moved. Migrating back restores the moved descriptions. (#309)
  • Code that creates contract types with bulk_create() must give a slug, since bulk_create() does not call save(), which derives it. (#309)
  • OpenAPI schema: the components NestedInvoice, NestedAccountingDimension and NestedContractLine are replaced by BriefInvoice, BriefAccountingDimension and BriefContractLine, with the same properties (on NetBox 4.6.10 or later; earlier 4.6 releases document the accounting dimension lists with the AccountingDimension component). Clients generated from the schema must be regenerated; the responses are unchanged. (#309)

New Features

Contract Lines and Units (#278)

Contract lines replace the contract costs (mrc, yrc, nrc) and the invoice templates. The new Unit model defines a billing method (one-time, recurring or usage-based) and the number of months one unit price covers; a Contract line has a description, quantity, unit price, unit, currency, start and end dates and accounting dimensions. Both have list, detail, edit, bulk import, bulk edit and bulk delete screens.

Contracts get a billable flag and three computed values: total contract value, yearly value and yearly billable value (which includes the lines of non-billable descendants).

On upgrade, a data migration converts the monthly, yearly and non-recurring costs and the invoice templates into contract lines (units "One-time", "Monthly", "Yearly") and prints a report. It can be run again with python manage.py convert_contract_lines. Every existing contract is billable. Invoices and invoice lines are not changed.

Invoices Generated from Contract Lines (#278)

The invoice add screen proposes the amount from the contract lines and previews the invoice lines that will be generated, with their amounts and total. Their quantities, unit prices and accounting dimensions can be changed, and lines without contract line added, before saving; the invoice and its lines are created in one step.

Invoice lines reference their contract line and carry their own quantity, unit and unit price, taken from the contract line by default and editable as long as the invoice is not posted (for example a discount on one invoice). Their amount is calculated as quantity x unit price. Migration 0047 copies the unit and unit price of the contract line into existing lines without changing their amounts.

Contract Line Amendments (#278, #309)

The unit price or quantity of a recurring or usage-based line can be amended from a date (Amend button, or POST contract-lines/{id}/amend/): the line ends the day before and a new line replaces it, invoiced periods keep their price, and the required reason is recorded in the change log. Amending has its own amend permission action (migration 0050), which can be limited with constraints; the Amend button is shown on the line page, in contract line tables and on the edit page only for the lines the user may amend.

Currency Consistency and Posted Invoice Locking (#278)

Contract lines, invoices and invoice lines must have the currency of their contract or invoice, and a non-billable child contract has the currency of its parent. The new read-only custom script "Report currency mismatches" lists existing mismatches without changing them.

Posted invoices are locked: their amounts, period and contracts, and the amounts of their lines, can no longer change, and lines can no longer be added or deleted. Accounting dimensions, comments and tags remain editable, and the status can change back to Draft.

GraphQL API (#309)

Contracts, contract lines, contract types, contract assignments, invoices, invoice lines, units, accounting dimensions and service providers can be queried and filtered in NetBox's GraphQL API, with permissions applied. It has the stored fields and relations; the computed contract and line values stay in the REST API, and an assigned object is resolved for the models of the default supported_models setting (see the API documentation).

Enhancements

  • #278 - Invoice lines have a readable name (<invoice number> line <id>) in search results, the change log and reports
  • #308 - Add the Journal tab to invoice lines, accounting dimensions, contract types and contract assignments
  • #308 - Filter forms offer NetBox's lookup modifiers (contains, starts with, is not, is empty, ...)
  • #308 - Add, edit, bulk edit and filter forms group their fields into sections (for contracts: Contract, Parties, Dates and terms, Billing, Tenancy)
  • #308 - The invoice and invoice line add screens support NetBox's quick add and partial refresh; values given in the page address (for example ?date= or ?period_start=) are kept by the invoice pre-fill instead of being replaced
  • #308 - The contract type description is a plain text field in the filter, bulk edit and import forms, and can be cleared in bulk
  • #308 - Invoice line tables (list, invoice page) show the linked ID by default, so a line can be opened; users who saved their own column choice add it from Configure Table
  • #308 - Refresh the translations and translate the new texts of 2.5.0 into French
  • #309 - The detail pages of the nine object types are built from NetBox's standard panels; their related tables are the tables of the corresponding lists filtered to the object, so their columns can be chosen with Configure Table on the list (#294)
  • #309 - Contract line tables decide their actions line by line: a locked line offers no Delete, and an amendable line offers Amend
  • #309 - Add the contract list filter invoice_id (UI and REST API): the contracts of an invoice
  • #309 - Contract types become NetBox organizational objects, with a slug, comments and an owner; service providers become NetBox primary objects, with a description and an owner (migrations 0051 and 0052). Both can be filtered by owner, and the owner can be set in bulk and imported. A contract type's slug is derived from its name when it is not given

Bug Fixes

  • #307 - The Contracts tab of assigned objects (sites, devices, circuits, ...) is shown to users with the view contract assignment permission; it was shown to superusers only, because it checked a permission of a non-existent contracts app
  • #307 - The REST endpoints serviceproviders/, contracttype/, accountingdimension/ and contractassignment/ ignored their filters (name, q, tag, contract, ...) and always returned the whole list
  • #307 - The OpenAPI schema documents external_party_object (contracts, and the contract nested in contract lines and assignments) and content_object (contract assignments) as objects instead of strings
  • #307 - The invoice line add form pre-fills the unit price and currency only from an invoice the user may view, and no longer fails with a server error when the invoice parameter is unknown or not a number
  • #307 - The Amend button of contract lines was shown to users with the change permission alone, who then got a "forbidden" page
  • #308 - Editing an existing invoice showed today's date in place of its date

Plugins

  • #308 - Every screen of the plugin is registered with register_model_view, so other plugins can add tabs and actions to any plugin object; page addresses do not change
  • #309 - Other plugins can add content to the left, right and full-width areas of every plugin page
  • #309 - The template shown at the bottom of assigned objects moved to netbox_contract/inc/contract_assignments_bottom.html, and the unused contract_list_bottom.html was removed

Deprecations

  • #278 - The contract fields mrc, yrc and nrc and the invoice templates are deprecated. They are kept (never deleted, shown with a "deprecated" badge) and hidden by default; the new plugin setting show_deprecated_fields (default False) shows them again. They remain in the bulk import and the REST API
  • #309 - REST API fields, to be removed by a later release (see the API documentation; read contracts/{id}/ or invoices/{id}/ instead):
    • Nested contract (contract of assignments and contract lines, parent of contracts): contract_type, external_party_object_type, external_party_object_id, external_party_object, external_reference, internal_party, tenant, start_date, end_date, initial_term, renewal_term, notice_period, currency, mrc, yrc, nrc, invoice_frequency, comments, documents; it will keep id, url, display, name and status
    • contracts of an invoice become brief contracts: the fields above and billable, total_contract_value, yearly_contract_value, yearly_billable_value, parent, tags, custom_fields, created, last_updated will be removed
    • contracts/?brief=true: contract_type, external_party_object_type, external_party_object_id, external_party_object, external_reference, internal_party, tenant, start_date, end_date, initial_term, renewal_term, currency, mrc, yrc, nrc, invoice_frequency, billable, comments, parent
    • invoices/?brief=true: date, template, contracts, period_start, period_end, currency, amount, comments

Other Changes

  • #278 - CI runs the tests against the NetBox v4.6.10 tag
  • #307 - The plugin no longer depends on drf_yasg, which NetBox does not use

REST API Changes

  • Added the following endpoints:
    • GET/POST /api/plugins/contracts/units/
    • GET/PUT/PATCH/DELETE /api/plugins/contracts/units/<id>/
    • GET/POST /api/plugins/contracts/contract-lines/
    • GET/PUT/PATCH/DELETE /api/plugins/contracts/contract-lines/<id>/
    • POST /api/plugins/contracts/contract-lines/<id>/amend/
  • netbox_contract.Contract
    • Add the billable boolean field
    • Add the read-only total_contract_value, yearly_contract_value and yearly_billable_value fields
    • Add the invoice_id filter
    • mrc, yrc and nrc are deprecated
  • netbox_contract.ContractType
    • Add the slug, comments and owner fields
    • The brief representation gains slug and description
  • netbox_contract.ServiceProvider
    • Add the description and owner fields
    • The brief representation gains slug and description
  • netbox_contract.Invoice
    • New invoices default to the draft status
    • template is deprecated
    • The nested invoice uses NetBox's brief representation (same fields)
  • netbox_contract.InvoiceLine
    • Add the contract_line, quantity, unit and unit_price fields; amount is calculated
    • The brief representation gains id and currency and no longer declares the non-existent name
  • netbox_contract.ContractLine
    • The brief representation (also used for the replaced line, replaces) includes start_date and end_date
  • netbox_contract.AccountingDimension
    • The nested accounting dimensions use NetBox's brief representation (same fields)

Full Changelog: v2.4.7...v2.5.0

Don't miss a new netbox-contract release

NewReleases is sending notifications on new releases.