Contracts in Business Made (/contracts, one opens at /contracts/<sk>) keeps agreements the business has issued (to a customer, an employee, someone else) or received (from a vendor, a landlord, a lender, an insurer). The list puts what needs a decision at the top.
The endpoints are under business-made/contracts (appengine business-made/contracts/contract.controller.ts, contract.service.ts, contract-terms.ts, contract-sla.ts), called with call_appengine. A contract is created and edited as a record, bm_contract, with repo_create and repo_update, the way the screen does. Activating, signing, renewing, terminating and posting have their own calls.
draft ──send for signature──→ out_for_signature ──signed──→ active ──end date passes──→ expired
│ │ │ └──renews automatically──→ active (new end date)
└──────────activate────────────────┴────────activate────────┤
└──terminate──→ terminatedThe screen shows Draft, Out for signature, Active, Expired and Terminated. An active contract also falls into one of these groups (bucket):
| Group | When |
|---|---|
Past notice (past_notice) | The notice date has gone and the end date hasn't come. |
Notice due (expiring) | The notice date is 0 to notice days away. With 30 days' notice, that's 60 to 30 days before the end. |
| Active | Anything earlier. |
The notice date is the end date minus Notice needed (days before the end). That's 30 days when not set.
Ask first
- What is it, and with whom?
- The type: service agreement, supplier agreement, lease, loan, prepaid, accrual, insurance, licence or permit, warranty, NDA, or other.
- The direction: issued by us or received by us.
- The other party: a customer, a vendor, an employee or someone else.
- Dates: start, end, notice needed, and whether it renews automatically (and for how many months each time).
- Who should be told about the notice date and renewals. Their email addresses go in People told about notice dates and renewals. The org owner is always told as well.
- The document: a PDF to keep, or one to send for signature, and who signs.
- For a supplier agreement: payment terms, lead time, return window, agreed prices, and the service levels promised.
- For a loan, prepaid or accrual: the amounts, the months, the bank account and the expense account. These post to Books.
Steps
1. Contracts: New contract
New contract opens the form. Its sections are:
- Contract
- Parties
- Term
- Terms
- Agreed prices
- Service levels
- Files and signing
- Schedule, shown for a loan, prepaid or accrual
- Linked records: a purchase order, bill, asset or business location
It saves as Draft.
Hands on: repo_create on bm_contract:
{ "name": "Acme supply agreement", "type": "supplier_agreement", "direction": "received", "status": "draft",
"counterparty": { "datatype": "bm_vendor", "id": "<vendor sk>", "name": "Acme Supply" },
"reference": "SUP-001", "startDate": "2026-10-01", "endDate": "2027-12-31",
"noticeDays": 30, "autoRenew": true, "renewalTermMonths": 12, "value": 5000,
"assignedTo": ["[email protected]"], "businessLocation": "<location name>",
"terms": { "paymentTerms": "net_15", "leadTimeDays": 7, "returnWindowDays": 30, "minOrderAmount": 500 },
"pricing": [ { "sku": "TEE-M", "unitCost": 3.5, "minQuantity": 0 }, { "sku": "TEE-M", "unitCost": 3, "minQuantity": 20 } ],
"sla": [ { "metric": "lead_time_days", "label": "Within a week", "target": 7, "unit": "days", "remedy": "5% credit" },
{ "metric": "fill_rate", "target": 95, "unit": "%" } ] }- Payment terms are
due_on_receipt,net_7…net_90,prepayorcustom. - Service level metrics are
lead_time_days,on_time_rate,fill_rate,return_rate,response_hours,resolution_hours,uptime_rateandother.
Check: GET business-made/contracts/<sk>/view returns the contract with its flags, notice date and hints. Tested: a draft with no PDF had the hint "Upload the agreement as a PDF to send it for signature."
When the contract is a supplier agreement, its prices, lead time, payment terms and return window are used by the purchase orders raised under it; see Purchase orders and receiving.
2. Contracts: Send for signature, or Activate
Send for signature (POST business-made/contracts/<sk>/send-for-signature) sends the contract's PDF through e-sign:
{ "signers": [ { "name": "Pat Lee", "email": "[email protected]" } ],
"spots": [ { "fileIndex": 0, "page": 1, "x": 100, "y": 600, "width": 180, "height": 40, "type": "signature", "role": "signer-1" } ],
"signingOrder": "parallel" }files(indexes into the contract's files) is optional. It defaults to every PDF on it.- The contract moves to Out for signature.
- When everyone has signed, the signed PDF is added to its files and it becomes Active. If the request is declined, cancelled, voided or expires, it goes back to Draft.
- How signing works is in E-sign documents.
Activate (POST …/<sk>/activate) is for a contract that's already in force, such as one signed on paper. It sets activatedOn to today, and the start date to today if there isn't one. If an e-sign request is still out, it's voided.
Stop:
- Sending for signature emails every signer. Show the signers and their emails, and wait for yes.
- Activating a loan, prepaid or accrual starts posting it to Books (step 5). Show the schedule, and wait for yes.
| Answer | Why |
|---|---|
| "Upload the agreement as a PDF, then send it for signature." | No PDF on the contract. Tested. |
| "Add who signs it." / "Give each signer a name and an email address." | |
| "Place a signature spot for | A signer with no signature spot. |
| "This contract is | |
| "Fix the schedule first: Pick the expense account it is booked to." | Activating an accrual without its expense account. Tested. |
Check: the contract reads Active, with its activation date. Tested: activating set activatedOn to the business date.
3. Contracts: notices and the end date
A daily job, Contract reminders and renewals (contracts-daily, 06:10), goes through every active contract and every contract out for signature:
- Out for signature: it picks up signing that finished.
- Notice due: when the contract enters the Notice due group, a notice email goes out. When it passes its notice date, an "ending" email goes out. Each is sent once per term.
- End date passed:
- If it renews automatically, the end date moves on by Each renewal adds (months), and a renewal email goes out. With no months set, it moves by the length of the first term, or 12 months.
- If it doesn't renew, the contract is marked Expired, and an expiry email goes out.
The emails go to everyone in People told about notice dates and renewals (assignedTo) and to the org owner's email. Each one links to the contract.
A contract near its end sends real email the next morning. An active contract dated inside its notice window gets a notice from the next 06:10 run. That includes one entered with old dates, and any test contract. Put real addresses in People told only when they should hear about it.
4. Contracts: Renew or Terminate
- Renew (
POST …/<sk>/renew{ months? }) moves the end date on now. It's for an active or expired contract. With nomonths, it moves by the contract's renewal months. Each renewal is listed under Renewals, showing the old end, the new end, who renewed it and when. Tested:{ months: 6 }moved 2027-12-31 to 2028-06-30, and the contract read Active. - Terminate (
POST …/<sk>/terminate{ date, reason }) ends an active contract, or one out for signature, on a date. The date defaults to today.- The end date becomes that date, and the old end date is kept in
termination.endDateBefore. - An e-sign request still out is voided.
- For a loan, prepaid or accrual, nothing posts after that date, and it can't end before a month that's already in Books.
- The end date becomes that date, and the old end date is kept in
Stop: renewing or terminating changes what the business is committed to. Show the contract, the new end date or the termination date, and the reason. Wait for yes. Nothing is sent to the other party. Tell them yourself if you're asked to.
| Answer | Why |
|---|---|
| "This contract is draft. Activate it before renewing." | Tested. |
| "Set the end date first; a contract with no end date has nothing to renew." | |
| "Say why it ends." | Terminate without a reason. Tested. |
| "Books already has this contract's month of |
Check: the contract reads Active with the new end date, or Terminated with the termination date and reason.
5. Contracts: Schedule (loans, prepaid costs, accruals)
For these three types, the contract's Schedule (schedule) holds the money over time. The Schedule section shows each month: what's posted, what's due and what's to come.
| Type | Fields | At the start | Each month |
|---|---|---|---|
| Loan | principal, annualRate, termMonths, paymentAmount (worked out when empty), firstDate (a month after the start when empty), bankAccountCode | Dr the bank (or cash), Cr Loans Payable 2600 | Dr Interest Expense 6800 and Dr 2600, Cr the bank |
| Prepaid | amount, termMonths, expenseAccountCode, bankAccountCode | Dr Prepaid Expenses 1300, Cr the bank | Dr the expense account, Cr 1300 |
| Accrual | monthlyAmount, expenseAccountCode | nothing | Dr the expense account, Cr Accrued Liabilities 2300 |
The accounts 1300, 2300, 2600 and 6800 are added to the chart the first time they are used. Some details:
- A prepaid linked to a bill (in Linked records) was paid through that bill, so its start entry isn't posted. Code that bill to Prepaid Expenses 1300.
- Posting starts in the month the contract was activated. Months before that aren't posted; they belong in the opening balances.
Tested: a loan of 12,000 at 6% over 24 months worked out a payment of 531.85 and interest of 764.37 in total. The first month's interest was 60.
The posting: a second daily job, Post contract schedules to Books (contracts-books, 02:20), posts every due month of every active, expired or terminated loan, prepaid and accrual. Each month posts once. Post due months now (POST …/<sk>/post) does the same for one contract, straight away. Tested: a loan starting next month posted nothing (posted: 0), with 24 months to come.
Stop: posting puts entries in the books. Show the months due and their amounts, and wait for yes.
Check: Books › Journal has an entry for each due month, with source contract. The month-end close's Contract accruals recorded item is ticked once every month due is posted; see Month-end close.
A schedule with a problem posts nothing, and only the hint says so. A loan with no amount, an accrual with no expense account, or a payment too small to cover the first month's interest is reported in the contract's hints. On an active contract, the job counts it as failed and moves on. Read the hints after every change.
6. Contracts: Service levels (supplier agreements)
The Service levels section shows each promised target beside the actual figure, worked out from the purchase orders raised under the contract (contractId), their deliveries and their returns:
- Lead time (days): approval to the last delivery, averaged over orders fully received.
- On-time delivery %: orders fully received by their expected date.
- Fill rate %: what was first received, out of what was ordered. It never goes over 100.
- Return rate %: what was sent back, out of what was received.
A unit replaced by the vendor isn't counted twice. Only orders placed during the contract's term count. Other metrics, such as response or uptime, show the target only (Target only). The figures are read with the contract (GET …/<sk>/view).
Tested: one order of 25, with 24 received the same day, read lead time 0, on time 100% and fill rate 96%. With a target of 95, the fill rate showed as met.
Check: each row reads met or missed against its target. If missed shows the remedy agreed.
The list
GET business-made/contracts/viewlists contracts with their group, notice date and days to the end. It filters bydirection,type,status,bucket,counterparty(<datatype>:<id>),businessLocationandq, and takessort.- The screen sorts by Ends soonest, Recently changed, Name or Value. It filters the same way.
- To answer "what's up for renewal", list
bucket=past_noticeandbucket=expiring.
When it's done
- The contract reads Active, with its dates, notice period, renewal setting and people to tell. Or it reads Expired or Terminated, with the reason.
- Its signed PDF is in Files and signing, or its paper original's place is noted (Where the paper original is kept).
- For a loan, prepaid or accrual, each due month is in Books › Journal.
- For a supplier agreement, its purchase orders carry its
contractId, and its service levels show actual figures.
What it can't do yet
- The Minimum order on a supplier agreement isn't enforced. It's stored and shown only; see Purchase orders and receiving.
- The org owner can't be left out of the notices. The owner's email is always added.
- No notice to the other party. Renewing, terminating and expiring are recorded here only.
- The service level counts include drafts. The order count shown with them includes draft orders, though only approved ones are measured.
Don'ts
- Don't activate, send for signature, renew, terminate or post without a yes on that contract.
- Don't save an active contract with an end date inside its notice window unless the people on it should be emailed.
- Don't put the other party's address in People told. It is for your own people.
- Don't change
status,renewalsorterminationwithrepo_update. Use Activate, Renew and Terminate. - Don't delete a loan, prepaid or accrual that has posted months. Its entries stay in the books with no contract behind them. Terminate it.