messages.ts
44.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
// vibe_erp SPA message bundles.
//
// Each locale is a flat key→string map. Keys use dot-notation
// grouped by area (nav.*, page.*, action.*, status.*, label.*).
//
// The framework's backend i18n uses ICU4J with MessageFormat
// patterns. The SPA uses plain strings for v1 — ICU MessageFormat
// in the browser (via @formatjs/intl-messageformat) is a v1.x
// enhancement when plural/gender/number formatting is needed
// client-side.
export type MessageKey = keyof typeof en
export const en = {
// ─── Navigation ────────────────────────────────────────────
'nav.overview': 'Overview',
'nav.dashboard': 'Dashboard',
'nav.catalog': 'Catalog & Partners',
'nav.items': 'Items',
'nav.uoms': 'Units of Measure',
'nav.partners': 'Partners',
'nav.inventory': 'Inventory',
'nav.locations': 'Locations',
'nav.balances': 'Stock Balances',
'nav.movements': 'Stock Movements',
'nav.orders': 'Orders',
'nav.salesOrders': 'Sales Orders',
'nav.purchaseOrders': 'Purchase Orders',
'nav.production': 'Production',
'nav.workOrders': 'Work Orders',
'nav.shopFloor': 'Shop Floor',
'nav.finance': 'Finance',
'nav.accounts': 'Chart of Accounts',
'nav.journalEntries': 'Journal Entries',
'nav.system': 'System',
'nav.users': 'Users',
'nav.roles': 'Roles',
'nav.metadataAdmin': 'Metadata',
// ─── Actions ───────────────────────────────────────────────
'action.confirm': 'Confirm',
'action.ship': 'Ship',
'action.receive': 'Receive',
'action.cancel': 'Cancel',
'action.start': 'Start',
'action.complete': 'Complete',
'action.create': 'Create',
'action.save': 'Save',
'action.back': '← Back',
'action.logout': 'Logout',
'action.signIn': 'Sign in',
'action.signingIn': 'Signing in…',
'action.creating': 'Creating…',
'action.addLine': '+ Add line',
'action.assign': 'Assign',
'action.revoke': 'Revoke',
'action.newItem': '+ New Item',
'action.newPartner': '+ New Partner',
'action.newLocation': '+ New Location',
'action.newOrder': '+ New Order',
'action.newWorkOrder': '+ New Work Order',
'action.newUser': '+ New User',
'action.newRole': '+ New Role',
'action.newAccount': '+ New Account',
'action.adjustStock': 'Adjust Stock',
'action.addField': 'Add Field',
'action.addSection': 'Add Section',
'action.discard': 'Discard',
'action.delete': 'Delete',
'action.newCustomField': 'New Custom Field',
// ─── Status badges ────────────────────────────────────────
'status.DRAFT': 'Draft',
'status.CONFIRMED': 'Confirmed',
'status.SHIPPED': 'Shipped',
'status.RECEIVED': 'Received',
'status.COMPLETED': 'Completed',
'status.CANCELLED': 'Cancelled',
'status.IN_PROGRESS': 'In Progress',
'status.PENDING': 'Pending',
'status.POSTED': 'Posted',
'status.SETTLED': 'Settled',
'status.REVERSED': 'Reversed',
// ─── Common labels ────────────────────────────────────────
'label.code': 'Code',
'label.name': 'Name',
'label.type': 'Type',
'label.status': 'Status',
'label.active': 'Active',
'label.email': 'Email',
'label.phone': 'Phone',
'label.total': 'Total',
'label.quantity': 'Quantity',
'label.unitPrice': 'Unit Price',
'label.date': 'Date',
'label.currency': 'Currency',
'label.description': 'Description',
'label.username': 'Username',
'label.password': 'Password',
'label.signedInAs': 'Signed in as',
'label.noRows': 'No rows.',
'label.loading': 'Loading…',
'label.error': 'Error',
// ─── Metadata admin ───────────────────────────────────────
'page.metadataAdmin.title': 'Metadata Admin',
'tab.entities': 'Entities',
'tab.customFields': 'Custom Fields',
'tab.permissions': 'Permissions',
'tab.menus': 'Menus',
'tab.forms': 'Forms',
'tab.listViews': 'List Views',
'page.formDesigner.title': 'Form Designer',
'page.listViewDesigner.title': 'List View Designer',
'label.slug': 'Slug',
'label.entity': 'Entity',
'label.purpose': 'Purpose',
'label.preview': 'Preview',
'label.source': 'Source',
'label.columns': 'Columns',
'label.filters': 'Filters',
'label.sorting': 'Sorting',
'label.pageSize': 'Page Size',
'label.fieldKey': 'Field Key',
'label.targetEntity': 'Target Entity',
'label.fieldType': 'Field Type',
'confirm.delete': 'Are you sure?',
// ─── Workflow / tasks ─────────────────────────────────────
'nav.workflow': 'Workflow',
'nav.tasks': 'Tasks',
'page.tasks.title': 'Pending Tasks',
'page.tasks.subtitle': 'Workflow tasks waiting for action',
'page.taskDetail.title': 'Task Detail',
// ─── Rules ────────────────────────────────────────────────
'tab.rules': 'Rules',
'label.triggerEvent': 'Trigger Event',
'label.conditions': 'Conditions',
'label.actions': 'Actions',
'label.enabled': 'Enabled',
'label.conditionLogic': 'Logic',
'action.newRule': 'New Rule',
'action.saving': 'Saving...',
'action.adjusting': 'Adjusting...',
'action.setBalance': 'Set Balance',
'action.saveChanges': 'Save Changes',
'action.newForm': '+ New Form',
'action.newListView': '+ New List View',
'action.addColumn': '+ Add Column',
'action.addFilter': '+ Add Filter',
'action.addCondition': '+ Add Condition',
'action.addAction': '+ Add Action',
'action.addInput': '+ Add input',
'action.addOperation': '+ Add operation',
'action.addSectionDivider': '+ Add Section Divider',
'action.saveListView': 'Save List View',
'action.edit': 'Edit',
'action.balances': 'Balances',
'action.selectItem': 'Select item...',
// ─── Page titles & subtitles ──────────────────────────────
'page.dashboard.welcome': 'Welcome',
'page.dashboard.subtitle': "The framework's buy-make-sell loop, end to end through the same Postgres.",
'page.dashboard.gettingStarted': 'Getting started',
'page.dashboard.gettingStartedDesc': "The framework's buy-make-sell loop, end to end.",
'page.dashboard.step1': 'Set up master data',
'page.dashboard.step1Desc': 'create',
'page.dashboard.step1DescItems': 'items',
'page.dashboard.step1DescPartners': 'partners',
'page.dashboard.step1DescAnd': ', and',
'page.dashboard.step1DescLocations': 'locations',
'page.dashboard.step1DescThen': '. Then',
'page.dashboard.step1DescAdjust': 'adjust stock',
'page.dashboard.step1DescEnd': 'to set opening balances.',
'page.dashboard.step2': 'Create a sales order',
'page.dashboard.step2Link': 'new order',
'page.dashboard.step2Desc': 'with line items. Confirm it — the system auto-generates production work orders and posts an AR journal entry with double-entry lines (DR Accounts Receivable, CR Revenue).',
'page.dashboard.step3': 'Walk the work order',
'page.dashboard.step3Desc1': 'start it, walk routing operations on the',
'page.dashboard.step3ShopFloor': 'Shop Floor',
'page.dashboard.step3Desc2': ', then complete it. Materials are consumed, finished goods credited.',
'page.dashboard.step4': 'Ship the sales order',
'page.dashboard.step4Desc1': 'stock leaves the warehouse, the AR journal entry settles. View the ledger in',
'page.dashboard.step4Movements': 'Movements',
'page.dashboard.step4Desc2': 'and double-entry lines in',
'page.dashboard.step4JE': 'Journal Entries',
'page.dashboard.step5': 'Restock via purchase',
'page.dashboard.step5Desc1': 'create a',
'page.dashboard.step5Link': 'purchase order',
'page.dashboard.step5Desc2': ', confirm, and receive into a warehouse. AP journal entry posts and settles.',
'page.dashboard.cardItems': 'Items',
'page.dashboard.cardPartners': 'Partners',
'page.dashboard.cardLocations': 'Locations',
'page.dashboard.cardWoInProgress': 'Work orders in progress',
'page.dashboard.cardSalesOrders': 'Sales orders',
'page.dashboard.cardPurchaseOrders': 'Purchase orders',
'page.dashboard.cardWorkOrders': 'Work orders',
'page.dashboard.cardJournalEntries': 'Journal entries',
'page.items.title': 'Items',
'page.items.subtitle': 'Catalog of items the framework can transact: raw materials, finished goods, services.',
'page.partners.title': 'Partners',
'page.partners.subtitle': 'Customers, suppliers, and dual-role partners.',
'page.locations.title': 'Locations',
'page.locations.subtitle': 'Warehouses, bins, and virtual locations the inventory PBC tracks.',
'page.balances.title': 'Stock Balances',
'page.balances.subtitle': 'On-hand quantities per (item, location). Updates atomically with every movement.',
'page.movements.title': 'Stock Movements',
'page.movements.subtitle': 'Append-only ledger of every change to inventory. Most-recent first.',
'page.salesOrders.title': 'Sales Orders',
'page.salesOrders.subtitle': 'Customer-facing orders. Confirm to auto-generate production work orders.',
'page.purchaseOrders.title': 'Purchase Orders',
'page.purchaseOrders.subtitle': 'Supplier-facing orders. Confirm and receive to credit inventory.',
'page.workOrders.title': 'Work Orders',
'page.workOrders.subtitle': 'Production orders with BOM inputs and routing operations.',
'page.users.title': 'Users',
'page.users.subtitle': 'User accounts in this instance. The admin role has all permissions.',
'page.roles.title': 'Roles',
'page.roles.subtitle': "Named bundles of permissions. The 'admin' role has all permissions by default.",
'page.accounts.title': 'Chart of Accounts',
'page.accounts.subtitle': 'GL accounts that journal entries debit and credit. 6 accounts seeded by default.',
'page.journalEntries.title': 'Journal Entries',
'page.journalEntries.subtitle': 'Double-entry GL entries posted by pbc-finance from order lifecycle events. Click a row to see debit/credit lines.',
'page.uoms.title': 'Units of Measure',
'page.uoms.subtitle': 'Seeded set of UoMs the catalog and inventory PBCs use to quantify items.',
'page.shopFloor.title': 'Shop Floor',
'page.shopFloor.subtitle': 'Live view of every work order in progress',
'page.shopFloor.refreshInterval': 'refreshes every {seconds}s',
'page.shopFloor.lastUpdate': 'last update',
'page.shopFloor.noWorkOrders': 'No work orders are in progress right now.',
'page.shopFloor.currentOp': 'Current operation',
'page.shopFloor.noRouting': 'No routing',
'page.shopFloor.actualMin': 'actual min',
'page.shopFloor.stdMin': 'std min',
'page.shopFloor.ops': 'ops',
// ─── Create / edit page titles ────────────────────────────
'page.createSalesOrder.title': 'New Sales Order',
'page.createSalesOrder.subtitle': 'Create a sales order. Confirming it will auto-generate production work orders.',
'page.createSalesOrder.submit': 'Create Sales Order',
'page.createSalesOrder.afterHint': 'After creation, confirm the order to auto-generate work orders.',
'page.createPurchaseOrder.title': 'New Purchase Order',
'page.createPurchaseOrder.subtitle': 'Order materials from a supplier. Confirm and receive to credit inventory.',
'page.createPurchaseOrder.submit': 'Create Purchase Order',
'page.createWorkOrder.title': 'New Work Order',
'page.createWorkOrder.subtitle': 'Create a production work order with optional BOM inputs and routing operations.',
'page.createWorkOrder.submit': 'Create Work Order',
'page.createLocation.title': 'New Location',
'page.createLocation.subtitle': 'Add a warehouse, bin, or virtual location for inventory tracking.',
'page.createLocation.submit': 'Create Location',
'page.createItem.title': 'New Item',
'page.createItem.subtitle': 'Add a raw material, finished good, or service to the catalog.',
'page.createItem.submit': 'Create Item',
'page.createPartner.title': 'New Partner',
'page.createPartner.subtitle': 'Add a customer, supplier, or dual-role partner.',
'page.createPartner.submit': 'Create Partner',
'page.createUser.title': 'New User',
'page.createUser.subtitle': 'Create a user account. Assign roles on the detail page after creation.',
'page.createUser.submit': 'Create User',
'page.editItem.title': 'Edit {code}',
'page.editItem.subtitle': 'Base UoM: {uom} (read-only after creation)',
'page.editPartner.title': 'Edit {code}',
'page.editPartner.subtitle': 'Partner code is read-only after creation',
// ─── Detail page strings ──────────────────────────────────
'page.salesOrderDetail.title': 'Sales Order {code}',
'page.salesOrderDetail.subtitle': 'Customer {partner}',
'page.salesOrderDetail.confirmMsg': 'Confirmed. pbc-finance has posted an AR journal entry.',
'page.salesOrderDetail.shipMsg': 'Shipped from {location}. Stock debited, journal entry settled.',
'page.salesOrderDetail.cancelMsg': 'Cancelled. pbc-finance has reversed any open journal entry.',
'page.salesOrderDetail.pickLocation': 'Pick a shipping location first.',
'page.purchaseOrderDetail.title': 'Purchase Order {code}',
'page.purchaseOrderDetail.subtitle': 'Supplier {partner}',
'page.purchaseOrderDetail.confirmMsg': 'Confirmed. pbc-finance has posted an AP journal entry.',
'page.purchaseOrderDetail.receiveMsg': 'Received into {location}. Stock credited, journal entry settled.',
'page.purchaseOrderDetail.cancelMsg': 'Cancelled. pbc-finance has reversed any open journal entry.',
'page.purchaseOrderDetail.pickLocation': 'Pick a receiving location first.',
'page.workOrderDetail.title': 'Work Order {code}',
'page.workOrderDetail.startMsg': 'Started. Operations can now be walked from the Shop Floor screen.',
'page.workOrderDetail.completeMsg': 'Completed. Materials issued, finished goods credited to {location}.',
'page.workOrderDetail.pickLocation': 'Pick an output location first.',
'page.userDetail.roles': 'Roles',
'page.userDetail.rolesHint': "Toggle roles on/off. Changes take effect on the user's next login.",
'page.userDetail.noRoles': 'No roles defined yet. Create one on the Roles page.',
// ─── Section / heading labels ─────────────────────────────
'label.lines': 'Lines',
'label.item': 'Item',
'label.lineNo': '#',
'label.qty': 'Qty',
'label.lineTotal': 'Line total',
'label.inventoryMovements': 'Inventory movements',
'label.journalEntries': 'Journal entries',
'label.noMovementsYet': 'No movements yet.',
'label.noEntriesYet': 'No entries yet.',
'label.viewAllJournalEntries': 'View all journal entries',
'label.delta': '\u0394',
'label.reason': 'Reason',
'label.reference': 'Reference',
'label.amount': 'Amount',
'label.bomInputs': 'BOM inputs',
'label.noBomLines': 'No BOM lines.',
'label.routingOperations': 'Routing operations',
'label.noRouting': 'No routing.',
'label.qtyPerUnit': 'Qty / unit',
'label.sourceLoc': 'Source loc',
'label.operation': 'Operation',
'label.workCenter': 'Work center',
'label.stdMin': 'Std min',
'label.orderCode': 'Order code',
'label.customer': 'Customer',
'label.supplier': 'Supplier',
'label.orderLines': 'Order lines',
'label.expectedDate': 'Expected date',
'label.woCode': 'WO code',
'label.outputItem': 'Output item',
'label.outputQty': 'Output qty',
'label.dueDate': 'Due date (optional)',
'label.bomInputsDesc': 'BOM inputs (materials consumed per unit of output)',
'label.noBomHint': 'No BOM lines. Output will be produced without consuming materials.',
'label.routingOpsDesc': 'Routing operations (sequential steps)',
'label.noRoutingHint': 'No routing. Work order completes in one step.',
'label.locationCode': 'Location code',
'label.locationType': 'Type',
'label.itemCode': 'Item code',
'label.itemType': 'Type',
'label.baseUom': 'Base UoM',
'label.descriptionOptional': 'Description (optional)',
'label.partnerCode': 'Partner code',
'label.emailOptional': 'Email (optional)',
'label.phoneOptional': 'Phone (optional)',
'label.displayName': 'Display name',
'label.quantityAbsolute': 'Quantity (absolute, not delta)',
'label.location': 'Location',
'label.occurred': 'Occurred',
'label.posted': 'Posted',
'label.order': 'Order',
'label.partner': 'Partner',
'label.output': 'Output',
'label.sourceSO': 'Source SO',
'label.inputsOps': 'Inputs / Ops',
'label.orderDate': 'Order date',
'label.expected': 'Expected',
'label.dimension': 'Dimension',
'label.accountType': 'Account Type',
'label.debit': 'Debit',
'label.credit': 'Credit',
'label.noJournalEntriesYet': 'No journal entries yet.',
'label.version': 'Version',
'label.noPendingTasks': 'No pending tasks',
// ─── Form designer labels ────────────────────────────────
'page.formDesigner.editTitle': 'Edit Form Definition',
'page.formDesigner.newTitle': 'New Form Definition',
'page.formDesigner.subtitle': 'Design a metadata-driven form with a live preview.',
'label.title': 'Title',
'label.entityName': 'Entity name',
'label.fields': 'Fields',
'label.livePreview': 'Live Preview',
'label.addFieldHint': 'Add at least one field with a key to see the preview.',
'label.section': 'Section',
'label.sectionTitle': 'Section title',
'label.removeSection': 'Remove section',
'label.label': 'Label',
'label.required': 'Required',
'label.req': 'Req',
'label.colSpan': 'Column span',
'label.toggleDetails': 'Toggle details',
'label.removeField': 'Remove field',
'label.labelEnglish': 'Label (English)',
'label.placeholder': 'Placeholder',
'label.helpText': 'Help text',
'label.widgetOverride': 'Widget override',
'label.widgetDefault': '(default)',
'label.visibilityCondition': 'Visibility condition',
'label.showWhen': 'Show when',
'label.always': '(always)',
'label.equals': 'equals',
'label.moveUp': 'Move up',
'label.moveDown': 'Move down',
'label.col': '{n} col',
'label.cols': '{n} cols',
// ─── List view designer labels ────────────────────────────
'page.listViewDesigner.editTitle': 'Edit List View',
'page.listViewDesigner.newTitle': 'New List View',
'page.listViewDesigner.subtitle': 'Configure columns, filters, sorting, and pagination for an entity list view.',
'label.general': 'General',
'label.show': 'Show',
'label.field': 'Field',
'label.format': 'Format',
'label.sortable': 'Sortable',
'label.noColumnsHint': 'No columns defined yet. Click "Add Column" to start.',
'label.noFiltersHint': 'No filters defined. Click "Add Filter" to add filterable fields.',
'label.fieldName': 'Field name',
'label.displayLabel': 'Display label',
'label.sortingPagination': 'Sorting & Pagination',
'label.defaultSortField': 'Default Sort Field',
'label.none': '-- none --',
'label.direction': 'Direction',
'label.ascending': 'Ascending',
'label.descending': 'Descending',
'label.addColumnsHint': 'Add visible columns with a field name to see a preview.',
'label.removeColumn': 'Remove column',
'label.removeFilter': 'Remove filter',
// ─── Metadata admin extras ────────────────────────────────
'page.metadataAdmin.subtitle': 'Browse and manage metadata definitions',
'label.pbc': 'PBC',
'label.table': 'Table',
'label.key': 'Key',
'label.path': 'Path',
'label.icon': 'Icon',
'label.sectionMeta': 'Section',
'label.orderMeta': 'Order',
'label.pii': 'PII',
'label.yes': 'Yes',
'label.no': 'No',
'label.allowedValues': 'Allowed values (comma-separated)',
'label.maxLength': 'Max length',
'label.labelEn': 'Label EN',
'label.labelZhCn': 'Label zh-CN',
// ─── Login page ───────────────────────────────────────────
'page.login.tagline': 'Composable ERP framework for the printing industry',
'page.login.passwordHint': 'The bootstrap admin password is printed to the application boot log on first start.',
'page.login.connectedTo': 'Connected to',
'page.login.connecting': 'Connecting...',
// ─── Adjust stock ─────────────────────────────────────────
'page.adjustStock.title': 'Adjust Stock',
'page.adjustStock.subtitle': "Set the on-hand quantity for an item at a location. Creates the balance row if it doesn't exist.",
'page.adjustStock.result': 'Balance set: {itemCode} @ location = {quantity}',
// ─── Task detail extras ───────────────────────────────────
'label.taskId': 'Task ID',
'label.process': 'Process',
'label.created': 'Created',
'label.assignee': 'Assignee',
'label.formKey': 'Form Key',
'label.variables': 'Variables',
// ─── User tasks column headers ────────────────────────────
'label.taskName': 'Task Name',
// ─── User status labels ───────────────────────────────────
'label.activeStatus': 'Active',
'label.disabled': 'Disabled',
// ─── Edit order pages ─────────────────────────────────────
'page.editLocation.title': 'Edit {code}',
'page.editLocation.subtitle': 'Type: {type} (read-only after creation)',
'page.editSalesOrder.title': 'Edit {code}',
'page.editSalesOrder.subtitle': 'Customer: {partner}',
'page.editSalesOrder.readOnlyHint': 'Order code, partner, lines, and currency are read-only after creation. Use this form to update custom fields.',
'page.editSalesOrder.notEditable': 'This sales order is in {status} status and cannot be edited. Only DRAFT orders are editable.',
'page.editPurchaseOrder.title': 'Edit {code}',
'page.editPurchaseOrder.subtitle': 'Supplier: {partner}',
'page.editPurchaseOrder.readOnlyHint': 'Order code, partner, lines, and currency are read-only after creation. Use this form to update custom fields.',
'page.editPurchaseOrder.notEditable': 'This purchase order is in {status} status and cannot be edited. Only DRAFT orders are editable.',
'page.editWorkOrder.title': 'Edit {code}',
'page.editWorkOrder.subtitle': 'Output: {item}',
'page.editWorkOrder.readOnlyHint': 'Order code, output item, BOM inputs, and routing operations are read-only after creation.',
'page.editWorkOrder.notEditable': 'This work order is in {status} status and cannot be edited. Only DRAFT orders are editable.',
} as const
export const zhCN: Record<MessageKey, string> = {
// ─── 导航 ──────────────────────────────────────────────────
'nav.overview': '概览',
'nav.dashboard': '仪表盘',
'nav.catalog': '产品与合作伙伴',
'nav.items': '物料',
'nav.uoms': '计量单位',
'nav.partners': '合作伙伴',
'nav.inventory': '库存',
'nav.locations': '库位',
'nav.balances': '库存余额',
'nav.movements': '库存变动',
'nav.orders': '订单',
'nav.salesOrders': '销售订单',
'nav.purchaseOrders': '采购订单',
'nav.production': '生产',
'nav.workOrders': '工单',
'nav.shopFloor': '车间看板',
'nav.finance': '财务',
'nav.accounts': '科目表',
'nav.journalEntries': '日记账',
'nav.system': '系统',
'nav.users': '用户',
'nav.roles': '角色',
'nav.metadataAdmin': '元数据',
// ─── 操作 ──────────────────────────────────────────────────
'action.confirm': '确认',
'action.ship': '发货',
'action.receive': '收货',
'action.cancel': '取消',
'action.start': '开始',
'action.complete': '完成',
'action.create': '创建',
'action.save': '保存',
'action.back': '← 返回',
'action.logout': '退出',
'action.signIn': '登录',
'action.signingIn': '登录中…',
'action.creating': '创建中…',
'action.addLine': '+ 添加行',
'action.assign': '分配',
'action.revoke': '撤销',
'action.newItem': '+ 新物料',
'action.newPartner': '+ 新合作伙伴',
'action.newLocation': '+ 新库位',
'action.newOrder': '+ 新订单',
'action.newWorkOrder': '+ 新工单',
'action.newUser': '+ 新用户',
'action.newRole': '+ 新角色',
'action.newAccount': '+ 新科目',
'action.adjustStock': '库存调整',
'action.addField': '添加字段',
'action.addSection': '添加分区',
'action.discard': '放弃',
'action.delete': '删除',
'action.newCustomField': '新建自定义字段',
// ─── 状态 ──────────────────────────────────────────────────
'status.DRAFT': '草稿',
'status.CONFIRMED': '已确认',
'status.SHIPPED': '已发货',
'status.RECEIVED': '已收货',
'status.COMPLETED': '已完成',
'status.CANCELLED': '已取消',
'status.IN_PROGRESS': '进行中',
'status.PENDING': '待处理',
'status.POSTED': '已过账',
'status.SETTLED': '已结算',
'status.REVERSED': '已冲销',
// ─── 通用标签 ──────────────────────────────────────────────
'label.code': '编码',
'label.name': '名称',
'label.type': '类型',
'label.status': '状态',
'label.active': '启用',
'label.email': '邮箱',
'label.phone': '电话',
'label.total': '合计',
'label.quantity': '数量',
'label.unitPrice': '单价',
'label.date': '日期',
'label.currency': '币种',
'label.description': '描述',
'label.username': '用户名',
'label.password': '密码',
'label.signedInAs': '当前用户',
'label.noRows': '暂无数据',
'label.loading': '加载中…',
'label.error': '错误',
// ─── 元数据管理 ────────────────────────────────────────────
'page.metadataAdmin.title': '元数据管理',
'tab.entities': '实体',
'tab.customFields': '自定义字段',
'tab.permissions': '权限',
'tab.menus': '菜单',
'tab.forms': '表单',
'tab.listViews': '列表视图',
'page.formDesigner.title': '表单设计器',
'page.listViewDesigner.title': '列表视图设计器',
'label.slug': '标识',
'label.entity': '实体',
'label.purpose': '用途',
'label.preview': '预览',
'label.source': '来源',
'label.columns': '列',
'label.filters': '筛选',
'label.sorting': '排序',
'label.pageSize': '每页行数',
'label.fieldKey': '字段键',
'label.targetEntity': '目标实体',
'label.fieldType': '字段类型',
'confirm.delete': '确定删除?',
// ─── 工作流 / 任务 ────────────────────────────────────────
'nav.workflow': '工作流',
'nav.tasks': '任务',
'page.tasks.title': '待办任务',
'page.tasks.subtitle': '等待处理的工作流任务',
'page.taskDetail.title': '任务详情',
// ─── 规则 ─────────────────────────────────────────────────
'tab.rules': '规则',
'label.triggerEvent': '触发事件',
'label.conditions': '条件',
'label.actions': '动作',
'label.enabled': '启用',
'label.conditionLogic': '逻辑',
'action.newRule': '新建规则',
'action.saving': '保存中...',
'action.adjusting': '调整中...',
'action.setBalance': '设置余额',
'action.saveChanges': '保存更改',
'action.newForm': '+ 新建表单',
'action.newListView': '+ 新建列表视图',
'action.addColumn': '+ 添加列',
'action.addFilter': '+ 添加筛选',
'action.addCondition': '+ 添加条件',
'action.addAction': '+ 添加动作',
'action.addInput': '+ 添加投入',
'action.addOperation': '+ 添加工序',
'action.addSectionDivider': '+ 添加分区线',
'action.saveListView': '保存列表视图',
'action.edit': '编辑',
'action.balances': '余额',
'action.selectItem': '选择物料...',
// ─── 页面标题与副标题 ─────────────────────────────────────
'page.dashboard.welcome': '欢迎',
'page.dashboard.subtitle': '框架的采购-生产-销售循环,端到端使用同一 Postgres。',
'page.dashboard.gettingStarted': '快速入门',
'page.dashboard.gettingStartedDesc': '框架的采购-生产-销售循环,端到端。',
'page.dashboard.step1': '设置主数据',
'page.dashboard.step1Desc': '创建',
'page.dashboard.step1DescItems': '物料',
'page.dashboard.step1DescPartners': '合作伙伴',
'page.dashboard.step1DescAnd': '和',
'page.dashboard.step1DescLocations': '库位',
'page.dashboard.step1DescThen': '。然后',
'page.dashboard.step1DescAdjust': '调整库存',
'page.dashboard.step1DescEnd': '设置期初余额。',
'page.dashboard.step2': '创建销售订单',
'page.dashboard.step2Link': '新订单',
'page.dashboard.step2Desc': '添加行项目。确认后系统自动生成生产工单,并过账 AR 日记账分录(借方应收账款,贷方收入)。',
'page.dashboard.step3': '执行工单',
'page.dashboard.step3Desc1': '启动它,在',
'page.dashboard.step3ShopFloor': '车间看板',
'page.dashboard.step3Desc2': '上完成工序。材料被消耗,成品入库。',
'page.dashboard.step4': '发货销售订单',
'page.dashboard.step4Desc1': '库存出库,AR 日记账结算。在',
'page.dashboard.step4Movements': '库存变动',
'page.dashboard.step4Desc2': '和',
'page.dashboard.step4JE': '日记账',
'page.dashboard.step5': '采购补货',
'page.dashboard.step5Desc1': '创建',
'page.dashboard.step5Link': '采购订单',
'page.dashboard.step5Desc2': ',确认并收货入库。AP 日记账过账并结算。',
'page.dashboard.cardItems': '物料',
'page.dashboard.cardPartners': '合作伙伴',
'page.dashboard.cardLocations': '库位',
'page.dashboard.cardWoInProgress': '进行中的工单',
'page.dashboard.cardSalesOrders': '销售订单',
'page.dashboard.cardPurchaseOrders': '采购订单',
'page.dashboard.cardWorkOrders': '工单',
'page.dashboard.cardJournalEntries': '日记账分录',
'page.items.title': '物料',
'page.items.subtitle': '框架可交易的物料目录:原材料、成品、服务。',
'page.partners.title': '合作伙伴',
'page.partners.subtitle': '客户、供应商及双重角色合作伙伴。',
'page.locations.title': '库位',
'page.locations.subtitle': '库存 PBC 跟踪的仓库、货位和虚拟库位。',
'page.balances.title': '库存余额',
'page.balances.subtitle': '按(物料, 库位)的在手数量。每次变动时原子更新。',
'page.movements.title': '库存变动',
'page.movements.subtitle': '库存变更的仅追加账本。最新的排在前面。',
'page.salesOrders.title': '销售订单',
'page.salesOrders.subtitle': '面向客户的订单。确认后自动生成生产工单。',
'page.purchaseOrders.title': '采购订单',
'page.purchaseOrders.subtitle': '面向供应商的订单。确认并收货以入库。',
'page.workOrders.title': '工单',
'page.workOrders.subtitle': '包含 BOM 投入和工艺路线的生产工单。',
'page.users.title': '用户',
'page.users.subtitle': '此实例中的用户账户。管理员角色拥有所有权限。',
'page.roles.title': '角色',
'page.roles.subtitle': "权限的命名组合。'admin' 角色默认拥有所有权限。",
'page.accounts.title': '科目表',
'page.accounts.subtitle': '日记账分录借贷的总账科目。默认预置 6 个科目。',
'page.journalEntries.title': '日记账分录',
'page.journalEntries.subtitle': 'pbc-finance 从订单生命周期事件过账的复式记账分录。点击行查看借贷明细。',
'page.uoms.title': '计量单位',
'page.uoms.subtitle': '产品目录和库存 PBC 用于量化物料的预置计量单位。',
'page.shopFloor.title': '车间看板',
'page.shopFloor.subtitle': '所有进行中工单的实时视图',
'page.shopFloor.refreshInterval': '每 {seconds} 秒刷新',
'page.shopFloor.lastUpdate': '最后更新',
'page.shopFloor.noWorkOrders': '目前没有进行中的工单。',
'page.shopFloor.currentOp': '当前工序',
'page.shopFloor.noRouting': '无工艺路线',
'page.shopFloor.actualMin': '实际分钟',
'page.shopFloor.stdMin': '标准分钟',
'page.shopFloor.ops': '工序',
// ─── 创建/编辑页面标题 ────────────────────────────────────
'page.createSalesOrder.title': '新建销售订单',
'page.createSalesOrder.subtitle': '创建销售订单。确认后将自动生成生产工单。',
'page.createSalesOrder.submit': '创建销售订单',
'page.createSalesOrder.afterHint': '创建后,确认订单以自动生成工单。',
'page.createPurchaseOrder.title': '新建采购订单',
'page.createPurchaseOrder.subtitle': '从供应商采购材料。确认并收货以入库。',
'page.createPurchaseOrder.submit': '创建采购订单',
'page.createWorkOrder.title': '新建工单',
'page.createWorkOrder.subtitle': '创建包含可选 BOM 投入和工艺路线的生产工单。',
'page.createWorkOrder.submit': '创建工单',
'page.createLocation.title': '新建库位',
'page.createLocation.subtitle': '添加仓库、货位或虚拟库位用于库存跟踪。',
'page.createLocation.submit': '创建库位',
'page.createItem.title': '新建物料',
'page.createItem.subtitle': '向目录添加原材料、成品或服务。',
'page.createItem.submit': '创建物料',
'page.createPartner.title': '新建合作伙伴',
'page.createPartner.subtitle': '添加客户、供应商或双重角色合作伙伴。',
'page.createPartner.submit': '创建合作伙伴',
'page.createUser.title': '新建用户',
'page.createUser.subtitle': '创建用户账户。创建后在详情页分配角色。',
'page.createUser.submit': '创建用户',
'page.editItem.title': '编辑 {code}',
'page.editItem.subtitle': '基础计量单位: {uom}(创建后只读)',
'page.editPartner.title': '编辑 {code}',
'page.editPartner.subtitle': '合作伙伴编码创建后只读',
// ─── 详情页文字 ──────────────────────────────────────────
'page.salesOrderDetail.title': '销售订单 {code}',
'page.salesOrderDetail.subtitle': '客户 {partner}',
'page.salesOrderDetail.confirmMsg': '已确认。pbc-finance 已过账 AR 日记账分录。',
'page.salesOrderDetail.shipMsg': '已从 {location} 发货。库存已扣减,日记账已结算。',
'page.salesOrderDetail.cancelMsg': '已取消。pbc-finance 已冲销所有未结日记账分录。',
'page.salesOrderDetail.pickLocation': '请先选择发货库位。',
'page.purchaseOrderDetail.title': '采购订单 {code}',
'page.purchaseOrderDetail.subtitle': '供应商 {partner}',
'page.purchaseOrderDetail.confirmMsg': '已确认。pbc-finance 已过账 AP 日记账分录。',
'page.purchaseOrderDetail.receiveMsg': '已收货至 {location}。库存已增加,日记账已结算。',
'page.purchaseOrderDetail.cancelMsg': '已取消。pbc-finance 已冲销所有未结日记账分录。',
'page.purchaseOrderDetail.pickLocation': '请先选择收货库位。',
'page.workOrderDetail.title': '工单 {code}',
'page.workOrderDetail.startMsg': '已启动。现在可以在车间看板上执行工序。',
'page.workOrderDetail.completeMsg': '已完成。材料已领用,成品已入库至 {location}。',
'page.workOrderDetail.pickLocation': '请先选择产出库位。',
'page.userDetail.roles': '角色',
'page.userDetail.rolesHint': '切换角色开关。更改在用户下次登录时生效。',
'page.userDetail.noRoles': '尚未定义角色。请先在角色页面创建角色。',
// ─── 区域/标题标签 ────────────────────────────────────────
'label.lines': '行项目',
'label.item': '物料',
'label.lineNo': '#',
'label.qty': '数量',
'label.lineTotal': '行合计',
'label.inventoryMovements': '库存变动',
'label.journalEntries': '日记账分录',
'label.noMovementsYet': '暂无变动。',
'label.noEntriesYet': '暂无分录。',
'label.viewAllJournalEntries': '查看全部日记账分录',
'label.delta': '\u0394',
'label.reason': '原因',
'label.reference': '参考',
'label.amount': '金额',
'label.bomInputs': 'BOM 投入',
'label.noBomLines': '无 BOM 行。',
'label.routingOperations': '工艺路线',
'label.noRouting': '无路线。',
'label.qtyPerUnit': '每单位用量',
'label.sourceLoc': '来源库位',
'label.operation': '工序',
'label.workCenter': '工作中心',
'label.stdMin': '标准分钟',
'label.orderCode': '订单编码',
'label.customer': '客户',
'label.supplier': '供应商',
'label.orderLines': '订单行',
'label.expectedDate': '预计日期',
'label.woCode': '工单编码',
'label.outputItem': '产出物料',
'label.outputQty': '产出数量',
'label.dueDate': '交期(可选)',
'label.bomInputsDesc': 'BOM 投入(每单位产出消耗的材料)',
'label.noBomHint': '无 BOM 行。产出将不消耗材料直接生产。',
'label.routingOpsDesc': '工艺路线(顺序步骤)',
'label.noRoutingHint': '无工艺路线。工单将一步完成。',
'label.locationCode': '库位编码',
'label.locationType': '类型',
'label.itemCode': '物料编码',
'label.itemType': '类型',
'label.baseUom': '基础计量单位',
'label.descriptionOptional': '描述(可选)',
'label.partnerCode': '合作伙伴编码',
'label.emailOptional': '邮箱(可选)',
'label.phoneOptional': '电话(可选)',
'label.displayName': '显示名称',
'label.quantityAbsolute': '数量(绝对值,非增量)',
'label.location': '库位',
'label.occurred': '发生时间',
'label.posted': '过账时间',
'label.order': '订单',
'label.partner': '合作伙伴',
'label.output': '产出',
'label.sourceSO': '源销售订单',
'label.inputsOps': '投入 / 工序',
'label.orderDate': '订单日期',
'label.expected': '预计',
'label.dimension': '量纲',
'label.accountType': '科目类型',
'label.debit': '借方',
'label.credit': '贷方',
'label.noJournalEntriesYet': '暂无日记账分录。',
'label.version': '版本',
'label.noPendingTasks': '无待办任务',
// ─── 表单设计器标签 ──────────────────────────────────────
'page.formDesigner.editTitle': '编辑表单定义',
'page.formDesigner.newTitle': '新建表单定义',
'page.formDesigner.subtitle': '设计带实时预览的元数据驱动表单。',
'label.title': '标题',
'label.entityName': '实体名称',
'label.fields': '字段',
'label.livePreview': '实时预览',
'label.addFieldHint': '添加至少一个带键名的字段以查看预览。',
'label.section': '分区',
'label.sectionTitle': '分区标题',
'label.removeSection': '移除分区',
'label.label': '标签',
'label.required': '必填',
'label.req': '必填',
'label.colSpan': '列跨度',
'label.toggleDetails': '切换详情',
'label.removeField': '移除字段',
'label.labelEnglish': '标签(英文)',
'label.placeholder': '占位符',
'label.helpText': '帮助文本',
'label.widgetOverride': '组件覆盖',
'label.widgetDefault': '(默认)',
'label.visibilityCondition': '可见性条件',
'label.showWhen': '当...时显示',
'label.always': '(始终)',
'label.equals': '等于',
'label.moveUp': '上移',
'label.moveDown': '下移',
'label.col': '{n} 列',
'label.cols': '{n} 列',
// ─── 列表视图设计器标签 ──────────────────────────────────
'page.listViewDesigner.editTitle': '编辑列表视图',
'page.listViewDesigner.newTitle': '新建列表视图',
'page.listViewDesigner.subtitle': '配置实体列表视图的列、筛选、排序和分页。',
'label.general': '基本信息',
'label.show': '显示',
'label.field': '字段',
'label.format': '格式',
'label.sortable': '可排序',
'label.noColumnsHint': '尚未定义列。点击"添加列"开始。',
'label.noFiltersHint': '尚未定义筛选。点击"添加筛选"添加可筛选字段。',
'label.fieldName': '字段名称',
'label.displayLabel': '显示标签',
'label.sortingPagination': '排序与分页',
'label.defaultSortField': '默认排序字段',
'label.none': '-- 无 --',
'label.direction': '方向',
'label.ascending': '升序',
'label.descending': '降序',
'label.addColumnsHint': '添加带字段名的可见列以查看预览。',
'label.removeColumn': '移除列',
'label.removeFilter': '移除筛选',
// ─── 元数据管理额外 ──────────────────────────────────────
'page.metadataAdmin.subtitle': '浏览和管理元数据定义',
'label.pbc': 'PBC',
'label.table': '表',
'label.key': '键',
'label.path': '路径',
'label.icon': '图标',
'label.sectionMeta': '分组',
'label.orderMeta': '排序',
'label.pii': '个人信息',
'label.yes': '是',
'label.no': '否',
'label.allowedValues': '允许值(逗号分隔)',
'label.maxLength': '最大长度',
'label.labelEn': '英文标签',
'label.labelZhCn': '中文标签',
// ─── 登录页 ──────────────────────────────────────────────
'page.login.tagline': '面向印刷行业的可组合 ERP 框架',
'page.login.passwordHint': '引导管理员密码在首次启动时输出到应用启动日志。',
'page.login.connectedTo': '已连接到',
'page.login.connecting': '连接中...',
// ─── 库存调整 ────────────────────────────────────────────
'page.adjustStock.title': '库存调整',
'page.adjustStock.subtitle': '设置某库位某物料的在手数量。如果余额行不存在则自动创建。',
'page.adjustStock.result': '余额已设置: {itemCode} @ 库位 = {quantity}',
// ─── 任务详情额外 ────────────────────────────────────────
'label.taskId': '任务 ID',
'label.process': '流程',
'label.created': '创建时间',
'label.assignee': '经办人',
'label.formKey': '表单键',
'label.variables': '变量',
// ─── 用户任务列头 ────────────────────────────────────────
'label.taskName': '任务名称',
// ─── 用户状态标签 ────────────────────────────────────────
'label.activeStatus': '已启用',
'label.disabled': '已禁用',
// ─── 编辑订单页面 ────────────────────────────────────────
'page.editLocation.title': '编辑 {code}',
'page.editLocation.subtitle': '类型: {type}(创建后只读)',
'page.editSalesOrder.title': '编辑 {code}',
'page.editSalesOrder.subtitle': '客户: {partner}',
'page.editSalesOrder.readOnlyHint': '订单编码、合作伙伴、行项目和币种创建后只读。使用此表单更新自定义字段。',
'page.editSalesOrder.notEditable': '此销售订单处于 {status} 状态,无法编辑。只有草稿状态的订单可编辑。',
'page.editPurchaseOrder.title': '编辑 {code}',
'page.editPurchaseOrder.subtitle': '供应商: {partner}',
'page.editPurchaseOrder.readOnlyHint': '订单编码、合作伙伴、行项目和币种创建后只读。使用此表单更新自定义字段。',
'page.editPurchaseOrder.notEditable': '此采购订单处于 {status} 状态,无法编辑。只有草稿状态的订单可编辑。',
'page.editWorkOrder.title': '编辑 {code}',
'page.editWorkOrder.subtitle': '产出: {item}',
'page.editWorkOrder.readOnlyHint': '工单编码、产出物料、BOM 投入和工艺路线创建后只读。',
'page.editWorkOrder.notEditable': '此工单处于 {status} 状态,无法编辑。只有草稿状态的工单可编辑。',
}
export const locales = {
'en-US': en,
'zh-CN': zhCN,
} as const
export type LocaleCode = keyof typeof locales