Skip to content

Maintenance Contracts

The maintenance contract is the centre of gravity of the whole suite. It answers four questions at once: which machines are covered, how often each one is visited, what has been pre-paid and how the customer pays. Every preventive work plan, every drawn-down spare part and every contract-priced invoice line comes back to it.

We will follow one contract all the way through: MC-0021, signed with Marina Plaza Hotels on 18 February 2026 and running from 1 March 2026 to 1 March 2027.

Menu: CRM → Maintenance Documents → Maintenance Contract.

Required licence

crm-maintenance. A document term (توجيه) is required, and it carries two things the contract cannot work without: the work-plan book and term that the generate button writes into, and — if you want the contract to reach the ledger — both a debit and a credit accounting side. See Maintenance Document Terms.

The Maintenance Contract screen: the header dates at the top and the Machines grid underneath

The Dates Are Not Called What You Expect

Start here, because nobody guesses it.

The contract's start and end dates live in fields labelled Warranty Start Date and Warranty End Date

There is no field called "contract start". The contract period is the Warranty Start Date and Warranty End Date pair in the header, with the Warranty Period between them. On MC-0021 those read 2026-03-01, 12 Month and 2027-03-01.

Both must be filled before you press Generate Work Plans, or the generation refuses to run — the whole visit series is stepped out between those two dates.

The rest of the header is unsurprising: contract type (Maintenance Contract here, as opposed to a Warranty Contract — see below), customer C-01188, contact CNT-0904, subsidiary (الذمة) the customer, responsible employee EMP-3001 Nahed El Gindy, machine, machine type and category, task template, serial number, currency and rate, number of periodic maintenances, a read-only number of performed visits, and the work-plan generation type.

The Machines Grid — Where the Schedule Really Lives

This is the important grid, and the seven Visit Type columns are the important part of it. Each machine line can carry up to seven frequencies, and each frequency has its own task template next to it, so the same machine can have a light monthly checklist and a heavier quarterly one.

MC-0021 covers three machines:

MachineVisit Type 1TemplateVisit Type 2TemplateTechnicianBuilding
MCH-00311 Chiller No. 1MonthlyTT-CHL-MQuarterlyTT-CHL-QEMP-2011BLD-MP01
MCH-00312 Chiller No. 2MonthlyTT-CHL-MQuarterlyTT-CHL-QEMP-2011BLD-MP01
MCH-00318 AHU – BasementMonthlyTT-AHU-MEMP-2011BLD-MP01

The same grid also carries the serial number, the machine's own warranty dates, building, floor and room, the maintenance period and number of visits, a planned visit date, the maintenance group, the technician, five classification columns and per-machine totals that are recalculated from the detail grids on every save.

Collect All Machines Related To The Customer is a shortcut worth knowing: it replaces the grid with every machine belonging to that customer that is not a sub-machine of another. On a customer with forty split units that saves an afternoon — but it replaces, so use it before you start hand-editing lines, not after.

The Visit schedule grid does nothing

Further down the main page there is a grid headed Visit schedule, holding a machine and a visit date. It looks exactly like the place you would enter "chiller 1, 1 April; chiller 1, 1 May; …" — and nothing reads it. The only code that touches it is a validation checking that the machine you picked also appears in the Machines grid.

No work plan, no order and no visit is ever produced from it. The visit series comes from the Visit Type columns above and the contract's start and end dates. Leave the visit-schedule grid empty.

The Terms page is in the same category: a grid of trouble level, trouble description, response time and remarks. It is an SLA table, it prints nicely if your implementer builds a form for it, and no code in the module reads it. Nothing measures a response time against it.

Pre-Paid Entitlement

The Spare parts and services page is where coverage actually lives, and coverage here means one thing only: a quantity, at a price.

Spare parts:

ItemQuantityUnit priceNet value
SP-FLT-14 Air filter 14 in24300.007,200.00
SP-OIL-05 Compressor oil 5 L4600.002,400.00
Total spare parts9,600.00

Services:

ServiceQuantityUnit priceNet value
MSV-01 Chiller periodic maintenance visit441,200.0052,800.00
Total services52,800.00

Those 44 visits are not a coincidence — they are exactly the 44 visits the work-plan generator will produce from the machine lines above. Pricing the contract and scheduling it are two sides of the same arithmetic, and it is worth doing them together.

Each line carries quantity, sold quantity and remaining quantity. As orders, invoices and returns are committed against this contract, the sold quantity rises and the remaining quantity falls, and a document that asks for more than is left is refused with a message naming the item and the contract. After the April order MO-0513, MC-0021 shows SP-FLT-14 sold 6 / remaining 18, SP-OIL-05 sold 1 / remaining 3, and MSV-01 sold 3 / remaining 41.

The contract price wins

MSV-01 is priced at 1,500.00 on the service catalogue and 1,200.00 on this contract; SP-FLT-14 is 350.00 on the sales price list and 300.00 here. When a document is raised against the contract, the contract price is what lands on the line. That is the mechanism sites use to give contract customers a better rate — and, if you price a line at zero, it is also the only sense in which covered work is "free".

What contract coverage does not do

Nothing compares the date of the work to the contract period or to any warranty. An order raised on a machine whose contract ended last year is priced and billed exactly like one on a live contract, with no warning. There is no free-versus-billed flag anywhere: the decision to charge the customer or absorb the cost is made by a person, every time.

Money and Payments

The contract carries a full money block, and on MC-0021 it reads:

Total (52,800.00 services + 9,600.00 spare parts)62,400.00
Sales tax 14 %8,736.00
Net value71,136.00

The Billing page holds the payment schedule. Marina Plaza pays quarterly:

#DateAmount
12026-03-0117,784.00
22026-06-0117,784.00
32026-09-0117,784.00
42026-12-0117,784.00
Total71,136.00

The schedule must add up

The contract is refused if the payment-schedule lines do not sum to exactly the money net value. That is a genuine, useful validation — if the contract will not save, add the schedule up first.

The buttons on that page — Generate Payments, Generate Receipt Voucher For Selected Payments, Generate Receipt Voucher and Collect Receipt Vouchers — are the standard payment-schedule helpers. Generating a receipt voucher opens a pre-filled voucher that you review and save; nothing is created behind your back.

What Committing the Contract Does

Accounting: yes, when the term is configured for it. Saving MC-0021 creates a full invoice-style entry over the spare-part and service lines — in our example debit receivable 71,136.00, credit spare-parts revenue 9,600.00, service revenue 52,800.00 and sales tax 8,736.00.

Both sides or nothing

The contract books only when its document term carries both a debit and a credit accounting side. With only one side filled it books nothing at all, silently and with no error message. If a signed contract shows no entry, that is the first thing to check — see How CRM Document Terms Work.

Stock: none. A maintenance contract never moves inventory.

The entry is created as a business request and processed in the background, which is why the save is instant. If processing fails, retry it from the Business Requests list view: filter for failed requests, select the rows, then More menu → Reprocess / Recommit.

Generating the Work Plans

This is press one of the two that make preventive maintenance happen. On 1 March 2026 Nahed opens MC-0021 and presses Generate Work Plans.

The generator walks every machine line, reads its Visit Type columns, and steps a date forward from the contract start date until it passes the contract end date. Then it groups the resulting rows into work-plan documents according to the header's work-plan generation type:

Generation typeOne work plan per…
Generate WorkPlan Based On Contract Priority (the default when the field is left empty)calendar month of the expected order date
Generate WorkPlan Based On Visit Typevisit type
Generate WorkPlan Based On Visit Type And Contract Priorityvisit type, per month

MC-0021 uses the first, and produces 44 expected-visit rows spread over 12 work-plan documents, WP-0087 through WP-0098. The arithmetic — why 44, why 12, and what each work plan contains — is on Maintenance Work Plans, which is also where you press the second button.

Two things must be in place before the button will work: the contract's start and end dates, and a work-plan book and term on the contract's document term. If either is missing the generation stops with a message and produces nothing.

Pressing Generate Work Plans again deletes work plans

This is not a safe refresh. When you press the button a second time, the generator keeps the work plans whose grouping key still matches — and deletes every other work plan this contract produced, together with the links from their machine lines to any orders already generated from them.

Add one machine to the contract, or change a visit type, or shift the contract end date, and work plans that used to exist can vanish. Before regenerating on a live contract, note which work plans have already produced orders. The orders themselves are not deleted, but the trail back from the work plan to them is.

Warranty Contracts

Contract type has a second value, Warranty Contract, and it is mostly not typed by hand: committing a maintenance order whose Order Type is Installation creates one automatically, copying the warranty period, the machine, the serial number, the customer, the contact and the spare-part, machine and service grids.

A generated warranty contract carries the full money block

Because the generated contract is a copy, it arrives with the same totals as the order it came from. If the warranty-contract term has accounting sides configured, the same amount is booked twice — once by the order or invoice, once by the generated contract. Leave the warranty-contract term without accounting sides. The mechanism is described on Maintenance Orders.

The Visits Number Page

The last page of the contract is a read-only list of the Maintenance Visit documents that point back at it. It fills up as visits are typed, and each one raises the header's number of performed visitsMC-0021 goes from 0 to 1 when MVIS-0055 is saved on 1 April 2026.

It is a genuinely useful "has anyone actually been there?" view, with one honest caveat: nothing generates those visit documents, so the counter only reflects the trips somebody bothered to type in. See Maintenance Visits.

Reporting

Reporting: none. This module ships no system reports, and this screen has no print form. To review contracts across customers, use the list view with saved criteria (المعايير) and export to Excel, or build a BI dashboard over the contract data.