service.json 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. {
  2. "page": {
  3. "notFound": "Service record not found",
  4. "updated": "Service record updated",
  5. "failedUpdate": "Failed to update service record",
  6. "deleteTitle": "Delete Service Record",
  7. "deleteDescription": "This will permanently delete this service record and all associated data. This cannot be undone.",
  8. "deleted": "Service record deleted",
  9. "failedDelete": "Failed to delete",
  10. "datesExpiredTitle": "Invoice Dates Expired",
  11. "datesExpiredDescription": "The invoice date or due date has passed. Would you like to update them before proceeding?",
  12. "datesExpiredUpdate": "Update dates and proceed",
  13. "datesExpiredProceed": "Proceed without changes",
  14. "datesExpiredUseToday": "Update to today's date",
  15. "datesExpiredCustomize": "Choose dates manually",
  16. "datesExpiredBack": "Back",
  17. "datesExpiredSetToday": "Set to today",
  18. "customFieldsInvalid": "Please fill in all required custom fields",
  19. "customFieldsSaveFailed": "Failed to save custom fields",
  20. "problems": {
  21. "title": "The job needs a title before it can be saved.",
  22. "negative": "Quantities, hours, prices and costs cannot be negative.",
  23. "partName": "Every priced part needs a name.",
  24. "laborDescription": "Every labour line with hours or a rate needs a description."
  25. }
  26. },
  27. "header": {
  28. "tabs": {
  29. "details": "Details",
  30. "images": "Images",
  31. "video": "Video",
  32. "documents": "Documents",
  33. "statusReports": "Status Reports"
  34. },
  35. "save": "Save",
  36. "pdf": "PDF",
  37. "email": "Email",
  38. "share": "Share",
  39. "notify": "Notify",
  40. "delete": "Delete",
  41. "unpaid": "Unpaid",
  42. "unsavedChanges": "Unsaved changes",
  43. "saved": "Saved",
  44. "joinCall": "Join video call",
  45. "moreActions": "More actions",
  46. "designMenu": "Invoice design",
  47. "designMenuLoading": "Checking which design this invoice prints with...",
  48. "designMenuExplain": "Sent to the customer on {date}, so it still prints with the design it was sent with. Choosing another changes only how it looks. What it says stays as it was sent, and the old look is not kept.",
  49. "designSentWith": "The design it was sent with",
  50. "designFollow": "Follow the current default",
  51. "designFollowNamed": "Follow the current default ({name})",
  52. "designDefaultName": "the current default",
  53. "designPickConfirmTitle": "Change this invoice to {name}?",
  54. "designPickConfirmBody": "Only the look changes. The workshop details, the customer, the payment terms and the totals stay exactly as they were sent. The design it prints with now is not kept, so this cannot be undone.",
  55. "designPickConfirm": "Change the design",
  56. "designPickDone": "This invoice now prints with {name}",
  57. "designPickFailed": "Could not change the design"
  58. },
  59. "basicInfo": {
  60. "title": "Basic Information",
  61. "invoiceDetails": "Invoice Details",
  62. "customerInfo": "Customer & Vehicle",
  63. "paid": "Paid",
  64. "markPaid": "Mark as Paid",
  65. "markUnpaid": "Mark as Unpaid",
  66. "vehicle": "Vehicle",
  67. "open": "Open",
  68. "customer": "Customer",
  69. "titleLabel": "Title *",
  70. "titlePlaceholder": "Oil Change",
  71. "date": "Date",
  72. "type": "Type",
  73. "mileage": "Mileage",
  74. "mileageMarine": "Engine Hours",
  75. "status": "Status",
  76. "technician": "Technician",
  77. "invoiceNumber": "Invoice Number",
  78. "invoiceDate": "Invoice Date",
  79. "invoiceDueDate": "Due Date",
  80. "typeOptions": {
  81. "maintenance": "Maintenance",
  82. "repair": "Repair",
  83. "upgrade": "Upgrade",
  84. "inspection": "Inspection"
  85. },
  86. "statusOptions": {
  87. "pending": "Pending",
  88. "in_progress": "In Progress",
  89. "waiting_parts": "Waiting Parts",
  90. "completed": "Completed"
  91. },
  92. "searchVehicles": "Search vehicles...",
  93. "noVehicleFound": "No vehicle found.",
  94. "techPicker": {
  95. "placeholder": "Select or type a name...",
  96. "searchPlaceholder": "Search or type name...",
  97. "useCustom": "Use \"{search}\"",
  98. "typePrompt": "Type a name...",
  99. "boardTechnicians": "Board Technicians",
  100. "teamMembers": "Team Members"
  101. },
  102. "design": "Invoice design",
  103. "designDefault": "Workshop default",
  104. "designFollowing": "Default ({name})",
  105. "designPinned": "This invoice reached the customer on {date}, so it keeps the design it went out with. A choice here applies only after it is unlocked and sent again. An owner can change the design now from Invoice design in the ⋮ menu at the top.",
  106. "designSaved": "Invoice design updated",
  107. "designSavedPinned": "Saved. This invoice keeps the design it was sent with until it is unlocked and sent again.",
  108. "designFollowingRule": "Default ({name}, {rule})",
  109. "designRule": {
  110. "parts_sale": "Parts-Only Sale"
  111. },
  112. "designSaveFailed": "Could not change the invoice design"
  113. },
  114. "parts": {
  115. "title": "Parts",
  116. "fromInventory": "From Inventory",
  117. "addPart": "Add Part",
  118. "partNumber": "Part #",
  119. "name": "Name",
  120. "qty": "Qty",
  121. "unitCost": "Cost",
  122. "unitCostHint": "Vendor cost (internal — not shown to customer)",
  123. "markupPercent": "Markup %",
  124. "markupPercentHint": "Markup applied to cost (internal — not shown to customer)",
  125. "applyMarkup": "Apply {percent}%",
  126. "applyMarkupHint": "Re-apply {percent}% markup to cost on every row",
  127. "unitPrice": "Unit Price",
  128. "total": "Total",
  129. "namePlaceholder": "Name *",
  130. "subtotal": "Parts Subtotal: {amount}",
  131. "inventoryTitle": "Select Part from Inventory",
  132. "searchInventory": "Search inventory...",
  133. "inStock": "{quantity} in stock",
  134. "noInventory": "No inventory parts found.",
  135. "scanBarcode": "Scan",
  136. "scanTitle": "Scan Barcode",
  137. "partFound": "Added \"{name}\" from inventory",
  138. "partNotFound": "No part found for barcode \"{barcode}\"",
  139. "deleteRow": "Delete row",
  140. "outOfStock": "Out of stock",
  141. "onBackorder": "On backorder ({count})",
  142. "nameMissingHint": "Rows without a part name are not saved."
  143. },
  144. "labor": {
  145. "title": "Labor & Services",
  146. "addLabor": "Add Labor",
  147. "addService": "Add Service",
  148. "addFinding": "Observation",
  149. "newObservation": "New Observation",
  150. "addExisting": "Show Existing ({count})",
  151. "fromPresets": "From Presets",
  152. "description": "Description",
  153. "hours": "Hours",
  154. "qty": "Qty",
  155. "qtyOrHours": "Unit / Hours",
  156. "rate": "Rate ({currency}/hr)",
  157. "total": "Total",
  158. "descriptionPlaceholder": "Description *",
  159. "subtotal": "Labor Subtotal: {amount}",
  160. "hourlyTag": "HR",
  161. "serviceTag": "SVC",
  162. "switchToHourlyHint": "Hourly: priced by hours worked (hours × rate/hr). Click to switch.",
  163. "switchToServiceHint": "Service: priced as a flat fee per unit. Click to switch.",
  164. "deleteRow": "Delete row",
  165. "descriptionMissingHint": "Rows without a description are not saved."
  166. },
  167. "totals": {
  168. "title": "Totals",
  169. "parts": "Parts",
  170. "labor": "Labor",
  171. "subtotal": "Subtotal",
  172. "subtotalInclTax": "Subtotal (incl. tax)",
  173. "discount": "Discount",
  174. "discountNone": "None",
  175. "discountPercentage": "Percentage",
  176. "discountFixed": "Fixed",
  177. "tax": "Tax",
  178. "taxIncluded": "Tax (incl.)",
  179. "total": "Total",
  180. "inclusiveModeHint": "Line item prices are entered with tax included. Totals show the net + tax breakdown.",
  181. "partsCost": "Parts cost (internal)"
  182. },
  183. "notes": {
  184. "title": "Notes",
  185. "public": "Public",
  186. "internal": "Internal",
  187. "publicPlaceholder": "Notes visible on the invoice...",
  188. "internalPlaceholder": "Internal notes (not shown on invoice)...",
  189. "publicHelper": "Shown on the invoice and shared documents",
  190. "internalHelper": "Only visible to your team",
  191. "aiWrite": "AI Write",
  192. "aiGenerated": "AI notes generated successfully",
  193. "aiGenerateFailed": "Failed to generate AI notes",
  194. "aiDialogTitle": "AI Write",
  195. "aiDialogDescription": "AI will analyze the parts and labor in this service record and generate a professional description. The result will be written to the currently selected note type.",
  196. "aiGenerate": "Generate",
  197. "aiOverwriteDescription": "The current note already has content. You can replace it or append the AI-generated text below it.",
  198. "aiOverwriteReplace": "Replace",
  199. "aiOverwriteAppend": "Append",
  200. "aiOverwriteCancel": "Cancel",
  201. "aiDontShowAgain": "Don't show this again"
  202. },
  203. "invoice": {
  204. "title": "Invoice Summary",
  205. "parts": "Parts",
  206. "labor": "Labor",
  207. "subtotal": "Subtotal",
  208. "subtotalInclTax": "Subtotal (incl. tax)",
  209. "discount": "Discount",
  210. "tax": "Tax ({rate}%)",
  211. "taxIncluded": "Tax (incl., {rate}%)",
  212. "total": "Total",
  213. "paid": "Paid",
  214. "balanceDue": "Balance Due",
  215. "paidBadge": "PAID",
  216. "entityLabel": "Invoice",
  217. "emailSubject": "Payment Confirmation",
  218. "statusEmailSubject": "Service Status Update",
  219. "markCompletedTitle": "Mark this invoice as completed?",
  220. "markCompletedDescription": "It has gone to the customer but is still marked as not finished, so it will keep showing on the work board.",
  221. "markCompletedConfirm": "Mark completed",
  222. "lockedFieldsetLabel": "Locked invoice, editing disabled"
  223. },
  224. "payments": {
  225. "title": "Payments",
  226. "markUnpaid": "Mark as Unpaid",
  227. "markPaid": "Mark as Paid",
  228. "recordPayment": "Record Payment",
  229. "totalPaid": "Total Paid",
  230. "amount": "Amount",
  231. "date": "Date",
  232. "method": "Method",
  233. "note": "Note",
  234. "notePlaceholder": "Optional note",
  235. "savePayment": "Save Payment",
  236. "methodOptions": {
  237. "cash": "Cash",
  238. "card": "Card",
  239. "transfer": "Transfer",
  240. "other": "Other"
  241. },
  242. "recorded": "Payment recorded",
  243. "markedPaid": "Marked as paid",
  244. "markedUnpaid": "Marked as unpaid",
  245. "deleted": "Payment deleted",
  246. "failedRecord": "Failed to record payment",
  247. "failedStatus": "Failed to update payment status",
  248. "failedDelete": "Failed to delete payment",
  249. "deleteTitle": "Delete Payment",
  250. "deleteDescription": "This will remove this payment record.",
  251. "failedPdf": "Failed to generate PDF invoice"
  252. },
  253. "attachments": {
  254. "deleteTitle": "Delete Attachment",
  255. "deleteDescription": "This will permanently delete this attachment. This cannot be undone.",
  256. "deleted": "Attachment deleted",
  257. "failedDelete": "Failed to delete",
  258. "images": "Images ({count})",
  259. "videos": "Videos ({count})",
  260. "diagnostics": "Diagnostic Reports ({count})",
  261. "documents": "Documents ({count})",
  262. "download": "Download",
  263. "close": "Close"
  264. },
  265. "share": {
  266. "title": "Share Invoice",
  267. "description": "Generate a public link that allows anyone to view and download this invoice without signing in.",
  268. "notifyTitle": "Notify {name}",
  269. "email": "Email",
  270. "noEmail": "(no email on file)",
  271. "sms": "SMS",
  272. "noPhone": "(no phone on file)",
  273. "sendNotification": "Send Notification",
  274. "revokeLink": "Revoke Link",
  275. "generateLink": "Generate Public Link",
  276. "emailSent": "Email sent",
  277. "failedEmail": "Failed to send email",
  278. "smsSent": "SMS sent",
  279. "failedSms": "Failed to send SMS",
  280. "copyLink": "Copy link"
  281. },
  282. "sidebar": {
  283. "vehicle": "Vehicle",
  284. "customer": "Customer",
  285. "vin": "VIN: {vin}",
  286. "mileageAtService": "Mileage at service: {mileage} {unit}",
  287. "engineHoursAtService": "Engine hours at service: {mileage} {unit}",
  288. "sharedLink": {
  289. "title": "Shared Link",
  290. "sharedOn": "Shared on {date}",
  291. "notViewed": "Not viewed yet",
  292. "viewedTimes": "Viewed {count, plural, one {# time} other {# times}}",
  293. "lastViewed": "Last {date}",
  294. "copyLink": "Copy link",
  295. "linkCopied": "Link copied"
  296. }
  297. },
  298. "images": {
  299. "title": "Service Images",
  300. "dropzone": "Drop images here or click to browse",
  301. "uploading": "Uploading...",
  302. "formats": "JPG, PNG, WebP — max 10MB each",
  303. "uploadingImages": "Uploading images...",
  304. "limitReached": "Image limit reached ({count}/{max})",
  305. "upgradePrompt": "Upgrade your plan to upload more images.",
  306. "onlyAllowed": "Only JPG, PNG, and WebP images are allowed. {names} skipped.",
  307. "onlyUploading": "Only uploading {count} image(s) to stay within limit.",
  308. "uploadingCount": "Uploading {count} image(s)...",
  309. "uploadedCount": "{count} image(s) uploaded",
  310. "uploadFailed": "Upload failed",
  311. "deleted": "Image deleted",
  312. "failedDelete": "Failed to delete image",
  313. "failedUpdate": "Failed to update",
  314. "description": "Description...",
  315. "invoice": "Invoice"
  316. },
  317. "videos": {
  318. "title": "Service Videos",
  319. "dropzone": "Drop videos here or click to browse",
  320. "uploading": "Uploading...",
  321. "formats": "MP4, WebM, MOV — max 10MB each",
  322. "uploadingVideos": "Uploading videos...",
  323. "uploadingCount": "Uploading {count} video(s)...",
  324. "uploadedCount": "{count} video(s) uploaded",
  325. "uploadFailed": "Upload failed",
  326. "deleted": "Video deleted",
  327. "failedDelete": "Failed to delete video",
  328. "failedUpdate": "Failed to update",
  329. "invoice": "Invoice"
  330. },
  331. "documents": {
  332. "diagnosticTitle": "Diagnostic Reports",
  333. "documentsTitle": "Documents",
  334. "dropzone": "Drop files here or click to browse",
  335. "uploading": "Uploading...",
  336. "diagnosticFormats": "PDF, CSV, TXT — max 10MB each",
  337. "documentFormats": "PDF, DOCX, XLSX, CSV, TXT — max 10MB each",
  338. "uploadingReports": "Uploading reports...",
  339. "uploadingDocuments": "Uploading documents...",
  340. "diagnosticLimitReached": "Diagnostic report limit reached ({count}/{max})",
  341. "documentLimitReached": "Document limit reached ({count}/{max})",
  342. "upgradePrompt": "Upgrade your plan to upload more.",
  343. "diagnosticLabel": "Diagnostic report",
  344. "documentLabel": "Document",
  345. "limitReachedToast": "{label} limit reached ({count}/{max}). Upgrade your plan for more.",
  346. "onlyUploading": "Only uploading {count} file(s) to stay within limit.",
  347. "uploadingCount": "Uploading {count} file(s)...",
  348. "uploadedCount": "{count} file(s) uploaded",
  349. "uploadFailed": "Upload failed",
  350. "deleted": "File deleted",
  351. "failedDelete": "Failed to delete file",
  352. "failedUpdate": "Failed to update",
  353. "invoice": "Invoice"
  354. },
  355. "schedule": {
  356. "title": "Schedule",
  357. "date": "Date",
  358. "startTime": "Start Time",
  359. "endTime": "End Time",
  360. "technician": "Technician",
  361. "selectTechnician": "Select technician...",
  362. "searchOrCreate": "Search or create technician...",
  363. "createTechnician": "Create \"{name}\"",
  364. "creating": "Creating...",
  365. "failedCreate": "Failed to create technician",
  366. "addNew": "+ Add New",
  367. "add": "Add",
  368. "newTechPlaceholder": "Technician name...",
  369. "assign": "Assign to Board",
  370. "assigned": "Assigned to work board",
  371. "failedAssign": "Failed to assign",
  372. "endBeforeStart": "End time must be after start time",
  373. "failedUpdate": "Failed to update schedule times",
  374. "splitCreated": "Job spans multiple days — continuation created for next day",
  375. "customTechnicians": "Custom",
  376. "readMore": "Read More",
  377. "setDefaults": "Set Defaults",
  378. "workBay": "Work bay",
  379. "selectWorkBay": "Select work bay...",
  380. "noWorkBay": "No work bay",
  381. "noTechnician": "No technician",
  382. "technicians": "Technicians",
  383. "otherTeamMembers": "Other team members",
  384. "makeTechnician": "Makes them a technician",
  385. "addSomeoneNew": "Add someone new",
  386. "notOnBoard": "Not on the board yet",
  387. "putOnBoard": "Put on board",
  388. "slotTaken": "{count, plural, one {This slot is already booked} other {This slot has # clashes}}",
  389. "anotherJob": "another job",
  390. "clashTechnician": "the technician is busy",
  391. "clashBay": "the bay is in use",
  392. "clashBoth": "both are taken",
  393. "bookedAnyway": "Saved anyway. Change the time, or pick the next free slot.",
  394. "pickNextAvailable": "Pick next available slot",
  395. "findingSlot": "Finding a slot…",
  396. "slotPicked": "Booked into the next free slot",
  397. "noSlotFound": "No free slot found in the next few weeks"
  398. },
  399. "notifications": {
  400. "title": "Customer Notifications",
  401. "viaSms": "via SMS",
  402. "viaEmail": "via Email",
  403. "justNow": "Just now",
  404. "minutesAgo": "{count}m ago",
  405. "hoursAgo": "{count}h ago",
  406. "daysAgo": "{count}d ago"
  407. },
  408. "table": {
  409. "warranty": "Warranty"
  410. },
  411. "warranty": {
  412. "title": "Warranty",
  413. "months": "Duration (months)",
  414. "notes": "Warranty Terms",
  415. "notesPlaceholder": "e.g. 12-month warranty on all parts and labor...",
  416. "expiresAt": "Expires",
  417. "presets": {
  418. "3months": "3 mo",
  419. "6months": "6 mo",
  420. "12months": "12 mo",
  421. "24months": "24 mo"
  422. },
  423. "status": {
  424. "active": "Active",
  425. "expiring": "Expiring",
  426. "expired": "Expired",
  427. "none": "N/A"
  428. },
  429. "statementLabel": "What the customer is told about warranty",
  430. "statement": {
  431. "none": "Not stated",
  432. "included": "Included",
  433. "not_included": "Not included"
  434. },
  435. "noneHint": "Nothing about warranty is printed on this document.",
  436. "mileageWithUnit": "Distance limit ({unit})",
  437. "notIncludedNotes": "Statement to the customer",
  438. "notIncludedPlaceholder": "e.g. No workshop warranty is offered on customer-supplied parts.",
  439. "printedHint": "Printed under the warranty on the document.",
  440. "notIncludedHint": "Leave empty and the document says that statutory rights are not affected.",
  441. "summaryMonths": "{count} mo"
  442. },
  443. "concerns": {
  444. "title": "Customer concerns",
  445. "hint": "Why the customer came in, in their own words. One row for each thing they mentioned.",
  446. "add": "Add another",
  447. "placeholder": "There is a noise from the back when I brake",
  448. "remove": "Remove this concern",
  449. "notAnswered": "Nothing found against this yet",
  450. "answered": "{count} finding(s) against this"
  451. },
  452. "videoCall": {
  453. "title": "Video call",
  454. "none": "No video call on this work order.",
  455. "needsSchedule": "Set a start time first. The meeting follows the schedule.",
  456. "add": "Add {provider} meeting",
  457. "addedHere": "added from this work order",
  458. "fromCalendar": "from the calendar event",
  459. "join": "Join",
  460. "copy": "Copy link",
  461. "copied": "Link copied",
  462. "remove": "Remove",
  463. "removeTitle": "Remove the video call?",
  464. "removeDescription": "The meeting is deleted at the provider. Anyone who already has the link can no longer join.",
  465. "created": "Meeting created. The link is on the work order.",
  466. "removed": "Meeting removed",
  467. "failed": "Something went wrong",
  468. "shareHint": "The customer only gets this link when you send it.",
  469. "shareHintNoChannel": "The customer only gets this link when you send it. No messaging channel is set up, so copy it into a message yourself.",
  470. "send": {
  471. "button": "Send to customer",
  472. "title": "Send the video call link",
  473. "description": "Send the join link to {name}.",
  474. "messageLabel": "Note (optional)",
  475. "messagePlaceholder": "Anything the customer should know before the call...",
  476. "linkAlwaysIncluded": "The join link is always added below your note.",
  477. "sms": "SMS",
  478. "email": "Email",
  479. "telegram": "Telegram",
  480. "noPhone": "(no phone)",
  481. "noEmail": "(no email)",
  482. "noTelegram": "(no chat linked)",
  483. "notAvailable": "(not set up)",
  484. "cancel": "Cancel",
  485. "send": "Send",
  486. "sent": "Video call link sent",
  487. "partlySent": "Sent by {sent}; not by {failed}",
  488. "failed": "Could not send the link"
  489. },
  490. "notify": {
  491. "invitation": "Hi {name}, your video call about the {vehicle} is on {when}. Join here: {url}",
  492. "invitationNoTime": "Hi {name}, here is the link for the video call about the {vehicle}: {url}",
  493. "joinLine": "Join the video call here: {url}",
  494. "emailSubject": "Video call about your {vehicle}"
  495. }
  496. }
  497. }