Development - Mago-DACH-Hub/documentation GitHub Wiki
To generate a new application you can use the tb-legacy tool as follows:
> cd {DevEnv_Path}\Standard\Applications
> tbl n {ApplicationName}
You'll then be asked a few questions.
-
{ApplicationName}
must be a valid non-existing folder name, only containing alphanumeric characters, '_' or '-'. - The name of your organisation has to fit the name set at microarea.it
- The description is the name that's shown in Mago
- The 4-chars short name is later used to create the license / .csm file at microarea.it
For further information, check out the TBLegacy wiki.
▌Example▐
PS C:\DEV\dev35\Standard\Applications> tbl n Comics
Welcome to the TBLegacy generator!
? What is the name of your organization? Zucchetti
? Give your app a description Comics App
? Application version 1.0.0.0
? Is it a codeless application? No
? Re-use ERP precompiled headers? Yes
? Name of the first module Comics
? Description of the module Comics module
? Module 4-chars short name CMIX
? Name of the first library ComicsDbl
force ..\..\..\..\Users\{User}\.yo-rc-global.json
create Comics\Application.config
create Comics\Comics.sln
create Comics\Comics.props
create Comics\Solutions\Comics.Solution.xml
create Comics\Solutions\Comics.Solution.Brand.xml
create Comics\Solutions\Modules\Comics.xml
create Comics\Fragments\Comics.xml
create Comics\Comics\Module.config
create Comics\Comics\DatabaseScript\Create\CreateInfo.xml
create Comics\Comics\DatabaseScript\Upgrade\UpgradeInfo.xml
create Comics\Comics\Menu\Comics.menu
create Comics\Comics\Files\Images\CompanyLogo.png
create Comics\Comics\Files\Images\SplashMenuManager.jpg
create Comics\Comics\Files\Images\Comics.png
create Comics\Comics\ModuleObjects\AddOnDatabaseObjects.xml
create Comics\Comics\ModuleObjects\ClientDocumentObjects.xml
create Comics\Comics\ModuleObjects\DatabaseObjects.xml
create Comics\Comics\ModuleObjects\DocumentObjects.xml
create Comics\Comics\ModuleObjects\Enums.xml
create Comics\Comics\ModuleObjects\EventHandlerObjects.xml
create Comics\Comics\EFCore\EFSchemaObjects.xml
create Comics\Comics\ComicsDbl\beginh.dex
create Comics\Comics\ComicsDbl\endh.dex
create Comics\Comics\ComicsDbl\stdafx.cpp
create Comics\Comics\ComicsDbl\stdafx.h
create Comics\Comics\ComicsDbl\ComicsDbl.vcxproj
create Comics\Comics\ComicsDbl\ComicsDbl.cpp
create Comics\Comics\ComicsDbl\ComicsDblInterface.cpp
No change to package.json was detected. No package manager install will be executed.
- Register the application in the Microarea portal
- Crypt the default module definition (
{DevEnv_Path}\Standard\Applications\{ApplicationName}\Solutions\Modules\{DefaultModuleName}.xml
) Download the returned.csm
file into the same folder. - Generate at least one serial number for your application, from the specific page of the portal
Alternatively,
open{DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\Module.config
and change the deployment policy from full to base to be able to license the module without the need of a serial number.e.g.
<Library name="ExampleDbl" sourcefolder="Dbl" deploymentpolicy="base" />
- Restart IIS (e.g. with
iisreset
) to make the LoginManager reload the list of available applications - Launch the Administration Console (
/Apps/AdministrationConsole/Release/
) and activate the new application - Upgrade the companies databases; even if there are no new tables present, it is needed to "brand" the DB with the new application
Alternatively, if you don't want a new application, but only a new module in an existing application, us TBLegacy like this:
> cd {DevEnv_Path}\Standard\Applications\{ApplicationName}
> tbl m {ModuleName}
You'll then be asked two questions.
-
{ModuleName}
must be a valid non-existing folder name, only containing alphanumeric characters, '_' or '-'. - The 4-chars short name is later used to create the license / .csm file at microarea.it
For further information, check out the TBLegacy wiki.
▌Example▐
PS C:\DEV\dev35\Standard\Applications\Comics> tbl m Manga
Welcome to the TBLegacy Module generator!
You are about to add a module to the Comics application.
? Description of the module Manga module
? Module 4-chars short name MNGA
force ..\..\..\..\..\Users\{User}\.yo-rc-global.json
create Solutions\Modules\Manga.xml
force Solutions\Comics.Solution.xml
create Fragments\Manga.xml
create Manga\Module.config
create Manga\DatabaseScript\Create\CreateInfo.xml
create Manga\DatabaseScript\Upgrade\UpgradeInfo.xml
create Manga\Menu\Manga.menu
create Manga\Files\Images\CompanyLogo.png
create Manga\Files\Images\SplashMenuManager.jpg
create Manga\Files\Images\Manga.png
create Manga\ModuleObjects\AddOnDatabaseObjects.xml
create Manga\ModuleObjects\ClientDocumentObjects.xml
create Manga\ModuleObjects\DatabaseObjects.xml
create Manga\ModuleObjects\DocumentObjects.xml
create Manga\ModuleObjects\Enums.xml
create Manga\ModuleObjects\EventHandlerObjects.xml
create Manga\EFCore\EFSchemaObjects.xml
No change to package.json was detected. No package manager install will be executed.
The first step when creating an application is to create the necessary database table.
All databases are defined and hosted in the Dbl
library of your application.
To create a new table you use the tblegacy
tool like this:
> cd {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}
> tbl t {TableName}
You'll then be asked a few questions.
-
{TableName}
is the physical name of the table used for the DB (w/ two-lettered prefix - e.g. "MA_" or "RM_"). It must be a non-existing valid name and cannot include spaces or special characters. - You can choose a
TableType
among master, master/detail or slave ("codeless" only). In the master/detail case, actually a pair of tables are generated; one intended to be a header, the other to contain lines (same name, but with a "Detail" suffix) - You have the option to "scaffold default fields" which might be recommended for beginners. This options will generate some fields inside the table, with predefined names, types and lenghts.
For further information, check out the TBLegacy wiki.
▌Example▐
PS C:\DEV\dev35\Standard\Applications\Comics\comics> tbl t CO_Collections
Welcome to the TBLegacy Table generator!
You are about to add a table to the comics module of the Comics application.
? Is it a codeless table? No
? Which is the hosting library ? ComicsDbl
? Which kind of table you want: master
? Scaffold some default fields (Y)
or start with no fields (n)? Yes
force ..\..\..\..\..\Users\{User}\.yo-rc-global.json
create DatabaseScript\Create\All\CO_Collections.sql
force DatabaseScript\Create\CreateInfo.xml
create ComicsDbl\TCollections.h
create ComicsDbl\TCollections.cpp
force ComicsDbl\DblInterface.cpp
force ComicsDbl\ComicsDbl.vcxproj
force ModuleObjects\DatabaseObjects.xml
force EFCore\EFSchemaObjects.xml
No change to package.json was detected. No package manager install will be executed.
Browse to {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Create
. Here you'll find the CreateInfo.xml
file, which defines the creation process of your module and the steps in which the tables will be created with their respective SQL script.
<!-- Example → CreateInfo.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<CreateInfo>
<ModuleInfo name="Comics" />
<Level1>
<Step numstep="1" script="CO_Collections.sql" />
<Step numstep="2" script="CO_Boxes.sql" />
<Step numstep="3" script="Alter_MA_Items.sql" />
<Step numstep="4" script="Alter_MA_InventoryReasons.sql" />
</Level1>
<Level2 />
</CreateInfo>
In this example, there are SQL scripts with a "Alter_" prefix, which are normally only used, when you upgarde your module or your module adds on to an existing module. Refer to this wiki's AddOns section.
TBLegacy will also have created a SQL script to create your DB table.
To update this script with your wanted fields, browse to {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Create\All
.
In addition, in case your module will be used with a system using Oracle in the future, you'll need to create a SQL script with the same name under the {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Create\Oracle
folder, which you might create yourself.
-- Example → ...\DatabaseScript\Create\All\CO_Collections.sql
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CO_Collections]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[CO_Collections] (
[Collection] [varchar] (20) NOT NULL,
[Description] [varchar] (32) NULL CONSTRAINT DF_Collections_Descri_00 DEFAULT (''),
[Notes] [varchar] (128) NULL CONSTRAINT DF_Collections_Note_00 DEFAULT (''),
[Disabled] [char] (1) NULL CONSTRAINT DF_Collections_Disab_00 DEFAULT ('0'),
CONSTRAINT [PK_Collections] PRIMARY KEY NONCLUSTERED (
[Collection]
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
-- Example → ...\DatabaseScript\Create\Oracle\CO_Collections.sql
CREATE TABLE "CO_COLLECTIONS" (
"COLLECTION" VARCHAR2 (20) NOT NULL,
"DESCRIPTION" VARCHAR2 (128) DEFAULT (''),
"NOTES" VARCHAR2 (32) DEFAULT (''),
"DISABLED" CHAR (1) DEFAULT ('0'),
CONSTRAINT "PK_COLLECTIONS" PRIMARY KEY (
"COLLECTION"
)
)
GO
For help regarding SQL syntax, use e.g. w3schools. You can also note down the fields and their respective type and length of your table, because you'll need it again later in development.
TBLegacy also updates the DatabaseObjects.xml
found at {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\ModuleObjects
, which only needs the definition of the namespace and whether it's a mastertable or not.
<!-- Example → DatabaseObjects.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<DatabaseObjects>
<Signature>Comics</Signature>
<Release>2</Release>
<Tables>
<Table namespace="Comics.Comics.ComicsDbl.CO_Collections" mastertable="true" >
<Create release="1" createstep="1" />
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_Boxes" mastertable="true" >
<Create release="2" createstep="2" />
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_CollectionsBox" mastertable="true" >
<Create release="2" createstep="3" />
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_CollectionsBoxDetails" >
<Create release="2" createstep="4" />
</Table>
</Tables>
</DatabaseObjects>
As well as the EFSchemaObjects.xml
found at {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\EFCore
, which is important for MagoCloud development and thus needs more defined information like columns, their type and such.
// TODO: Move ↓ to MagoCloud development
<!-- Simplified Example → EFSchemaObjects.xml -->
<?xml version="1.0" encoding="utf-8"?>
<DatabaseObjects version="1">
<Signature>Comics</Signature>
<Release>2</Release>
<Tables>
<Table namespace="Comics.Comics.ComicsDbl.CO_Collections" mastertable="true">
<DocumentationInfo localizable_1="true">Collections master table</DocumentationInfo>
<Create release="1" createstep="1" />
<Columns>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="20">Collection</SchemaInfo>
<DocumentationInfo localizable_1="true" mandatory="true">Collections code</DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="128">Description</SchemaInfo>
<DocumentationInfo localizable_1="true">Collections description</DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="32">Notes</SchemaInfo>
<DocumentationInfo localizable_1="true">Collections notes</DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="1">Disabled</SchemaInfo>
<DocumentationInfo localizable_1="true">Collections disabled</DocumentationInfo>
</Column>
</Columns>
<PrimaryKey name="PK_Collections" type="NONCLUSTERED">
<Segments>Collection</Segments>
</PrimaryKey>
<Indexes/>
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_Boxes" mastertable="true">
<DocumentationInfo localizable_1="true">Boxes master table</DocumentationInfo>
<Create release="2" createstep="2" />
[...]
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_CollectionsBox" mastertable="true">
<DocumentationInfo localizable_1="true">CollectionsBox header</DocumentationInfo>
<Create release="2" createstep="3" />
<Columns>
[...]
</Columns>
<PrimaryKey name="PK_CollectionsBox" type="NONCLUSTERED">
<Segments>DocID</Segments>
</PrimaryKey>
<Indexes/>
</Table>
<Table namespace="Comics.Comics.ComicsDbl.CO_CollectionsBoxDetails">
<DocumentationInfo localizable_1="true">CollectionsBox lines</DocumentationInfo>
<Create release="2" createstep="4" />
<Columns>
<Column>
<SchemaInfo localizable_1="true" type="Long" defaultvalue="0" length="0">DocID</SchemaInfo>
<DocumentationInfo localizable_1="true" mandatory="true">Document ID</DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="Long" defaultvalue="0" length="0">DocSubID</SchemaInfo>
<DocumentationInfo localizable_1="true">Line Sub-ID</DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="10">Code</SchemaInfo>
<DocumentationInfo localizable_1="true" mandatory="true"></DocumentationInfo>
</Column>
<Column>
<SchemaInfo localizable_1="true" type="String" defaultvalue="" length="128">Description</SchemaInfo>
<DocumentationInfo localizable_1="true"></DocumentationInfo>
</Column>
</Columns>
<PrimaryKey name="PK_CollectionsBoxDetails" type="NONCLUSTERED">
<Segments>DocID, DocSubID</Segments>
</PrimaryKey>
<ForeignKeys>
<ForeignKey name="FK_CollectionsBoxDetails_CollectionsBox_00" on="CollectionsBox" onns="Comics.Comics.ComicsDbl.CO_CollectionsBox">
<FKSegments>DocID</FKSegments>
<PKSegments>DocID</PKSegments>
</ForeignKey>
</ForeignKeys>
<Indexes/>
</Table>
</Tables>
</DatabaseObjects>
Your next step is starting the Mago AdministrationConsole
and create/update database structure
on your company to actually create the tables in your database.
In case you don't develop a module from the ground up, it might be necessery to update a module by creating an additional table or alter an already existing table.
The steps in 2.1.1. are still important, so make sure all your data is correct regarding your table, its columns and the release number in the DatabaseObjects.xml
, EFSchemaObjects.xml
and additionally in the Interface.cpp of your hosting library.
/* Simplified Example → ...\ComicsDbl\ComicsDblInterface.cpp*/
BEGIN_ADDON_INTERFACE() → BEGIN_ADDON_INTERFACE()
DATABASE_RELEASE(1) → DATABASE_RELEASE(2)
//... → //...
END_ADDON_INTERFACE() → END_ADDON_INTERFACE()
When you actually have to update an existing table, create a SQL script in {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Upgrade\All\Release_{ReleaseNo}
. The naming convention for these update scripts is Alter_{TableName}
.
Again, for sake, you need to provide a Oracle script in in {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Upgrade\Oracle\Release_{ReleaseNo}
as well.
-- Example → ...\DatabaseScript\Upgrade\All\Release_2\Alter_COCollections.sql
IF EXISTS ( SELECT dbo.syscolumns.name
FROM dbo.syscolumns, dbo.sysobjects
WHERE dbo.sysobjects.name = 'CO_Collections'
AND dbo.sysobjects.id = dbo.syscolumns.id
AND dbo.syscolumns.name = 'Notes')
BEGIN
ALTER TABLE [dbo].[CO_Collections]
ALTER COLUMN [Notes] [varchar] (256)
END
GO
-- Example → ...\DatabaseScript\Upgrade\Oracle\Release_2\Alter_COCollections.sql
ALTER TABLE "CO_COLLECTIONS"
MODIFY "NOTES" VARCHAR2 (256)
GO
Lastly, add a "DBRel" node in {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\DatabaseScript\Upgrade\UpgradeInfo.xml
.
<!-- Example → UpgradeInfo.xml -->
<?xml version="1.0" encoding="utf-8"?>
<UpgradeInfo>
<ModuleInfo name="Comics" />
<DBRel numrel="2">
<Level1>
<Step numstep="1" script="CO_Collections.sql" />
</Level1>
</DBRel>
</UpgradeInfo>
It's important that numrel
is the same as {ReleaseNo}
in the folder name of your update scripts.
Your next step is starting the Mago AdministrationConsole
and create/update database structure
on your company to actually create the tables in your database.
The TBLegacy Table Generator created a .cpp
and a .h
file for your table (that still need to be modified so that they include the defined columns of your table) and registers the class into your Library Interface.
/* Example → ComicsDblInterface.cpp */
BEGIN_TABLES()
BEGIN_REGISTER_TABLES()
REGISTER_TABLE (TCollections)
END_REGISTER_TABLES()
END_TABLES()
In the .h
file of your class, you have to define your columns as variables.
The naming convention is f_{ColumnName}
.
/* Example → TCollections.h */
#pragma once
#include "beginh.dex"
/////////////////////////////////////////////////////////////////////////////
class TB_EXPORT TCollections : public SqlRecord
{
DECLARE_DYNCREATE(TCollections)
public:
DataStr f_Collection;
DataStr f_Description;
DataStr f_Notes;
DataBool f_Disabled;
public:
TCollections(BOOL bCallInit = TRUE);
public:
virtual void BindRecord();
public:
static LPCTSTR GetStaticName();
};
#include "endh.dex"
These "Data" types are special types defined and used by Microarea that are all derived from DataObj
.
If you have doubt of what type to use, search for a already existing database column with the same type as yours in the ERP.sln
.
Possible datatypes include amongst others:
DataBool ← boolean // represented with char(1) on the DB
DataDate ← datetime
DataDbl ← double / float // represented with float on the DB (TODO: why? what's special for Dbl?)
DataEnum ← enumartions // represented with int on the DB (like DocumentType, LineType and such)
DataGuid ← guids // 'Globally Unique Identifier' (or 'Universally Unique Identifier'); probably represented with uniqueidentifier on the DB
DataInt ← integer // represented with int or smallint on the DB
DataLng ← long // represented with int on the DB (used for Ids)
DataMon ← double / float // represented with money on the DB
DataObj ← object
DataPerc ← double / float // represented with float on the DB, specifically used to represent a percentage number (like Discount)
DataQty ← double / float // represented with float on the DB
DataStr ← string // represented with varchar on the DB (used for Ids)
DataText ← string // represented with ntext on the DB (i.e. long strings)
After you're done with the header file, continue with the cpp portion of your class.
/* Example → TCollections.cpp */
#include "stdafx.h"
#include "TCollections.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// class TCollections Implementation
/////////////////////////////////////////////////////////////////////////////
//
//=============================================================================
IMPLEMENT_DYNCREATE(TCollections, SqlRecord)
//-----------------------------------------------------------------------------
TCollections::TCollections(BOOL bCallInit)
:
SqlRecord (GetStaticName()),
f_Disabled(FALSE)
{
f_Collection.SetUpperCase();
BindRecord();
if (bCallInit) Init();
}
//-----------------------------------------------------------------------------
void TCollections::BindRecord()
{
BEGIN_BIND_DATA();
BIND_DATA (_NS_FLD("Collection"), f_Collection);
BIND_DATA (_NS_FLD("Description"), f_Description);
BIND_DATA (_NS_FLD("Notes"), f_Notes);
BIND_DATA (_NS_FLD("Disabled"), f_Disabled);
BIND_TB_GUID();
END_BIND_DATA();
}
//-----------------------------------------------------------------------------
LPCTSTR TCollections::GetStaticName() { return _NS_TBL("CO_Collections"); }
In the constructor, you can initialise f_Disabled
with FALSE
since it's a boolean that defined to default to 0
.
It's also courtesy to set your Primary Key (in this case f_Collection
) to uppercase to improve the comparablity and minimize errors.
In addition to that, you have to bind your table columns to your in the header file defined variables in the BindRecord()
method.
To create a Document we need 2 libraries:
- Document library └ houses the code for the documents (like logic checks, click commands or database lookups)
- Components library
To create each type of library you can use the TBLegacy-tool like this:
> cd {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}
> tbl l {LibraryName}
You'll then be asked a question.
-
{LibraryName}
is used to name its containing folder. It must be a valid non-existing folder name, only containing alphanumeric characters, '_' or '-'. - As the usual case is that the library makes use of some resources defined in ERP, it may be useful to re-use ERP precompiled headers to save compilation time. (Note KS: when trying with Comics example, this option didn't make a difference in code, as far as I could see)
For further information, check out the TBLegacy wiki.
▌Example → Documents Library▐
PS C:\DEV\dev35\Standard\Applications\Comics\comics> tbl l ComicsDocuments
Welcome to the TBLegacy Table generator!
You are about to add a library to the Comics module of the Comics application.
? Re-Use ERP precompiled headers? (y/N) No
force ..\..\..\..\..\Users\{User}\.yo-rc-global.json
create ComicsDocuments\beginh.dex
create ComicsDocuments\endh.dex
create ComicsDocuments\stdafx.cpp
create ComicsDocuments\stdafx.h
create ComicsDocuments\ComicsDocuments.vcxproj
create ComicsDocuments\ComicsDocuments.cpp
create ComicsDocuments\ComicsDocumentsInterface.cpp
force Module.config
force ../Comics.sln
No change to package.json was detected. No package manager install will be executed.
▌Example → Components Library▐
PS C:\DEV\dev35\Standard\Applications\Comics\comics> tbl l ComicsComponents
Welcome to the TBLegacy Table generator!
You are about to add a library to the comics module of the Comics application.
? Re-Use ERP precompiled headers? (y/N) No
force ..\..\..\..\..\Users\{User}\.yo-rc-global.json
create ComicsComponents\beginh.dex
create ComicsComponents\endh.dex
create ComicsComponents\stdafx.cpp
create ComicsComponents\stdafx.h
create ComicsComponents\ComicsComponents.vcxproj
create ComicsComponents\ComicsComponents.cpp
create ComicsComponents\ComicsComponentsbInterface.cpp
force Module.config
force ../Comics.sln
No change to package.json was detected. No package manager install will be executed.
After we created those two libraries we can also create a document through TBLegacy
To create each type of library you can use the TBLegacy-tool like this:
> cd {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}
> tbl d {DocumentName}
You'll then be asked a few questions.
- It is checked that a document with
{DocumentName}
does not exist (in the ModuleObjects folder). - A codeless document is defined via metadata only, there is no C++ wrapper class. A codeless document can exists in a non-codeless application, but the vice-versa is not supported out-of-the-box.
- The Hosting Library should be the Documents Library to host the document.
- It allows to choose among master and master/detail. The first generates a document containing just a header (
DBTMaster
). The second generates a document with a header (DBTMaster
) and a detail (DBTSlaveBuffered
). - If the document is a master/detail type, the name of the details table is inferred by adding Details to the master name.
- Library for ADM definition should be the Components Library.
- If you don't scaffold default UI, the UI is left empty, with just a containing frame, a default view and an empty tile.
For further information, check out the TBLegacy wiki.
▌Example▐
C:\DEV\dev35\Standard\Applications\Comics\Comics> tbl d Collections
Welcome to the TBLegacy Document generator!
You are about to add a document to the Comics module of the Comics application.
? Is it a codeless document? No
? Which is the hosting library ? ComicsDocuments
? Which kind of document you want: master
? Set the main form title Collections document
? Which library contains the table definition ? ComicsDbl
? Which is the master table? TCollections
? What is the master table phisical name? CO_Collections
? Which library will contain the ADM definition ? ComicsComponents
? Scaffold some default UI (Y)
or start with empty UI (n)? Yes
force ..\..\..\..\..\..\Users\schkev\.yo-rc-global.json
create ComicsComponents\ADMCollections.h
create ComicsComponents\ADMCollections.cpp
force ComicsComponents\ComicsComponents.vcxproj
create ComicsDocuments\DCollections.h
create ComicsDocuments\DCollections.cpp
create ComicsDocuments\UICollections.hjson
force ComicsDocuments\ComicsDocumentsInterface.cpp
force ComicsDocuments\ComicsDocuments.vcxproj
create ModuleObjects\Collections\Description\Dbts.xml
create ModuleObjects\Collections\Description\Defaults.xml
create ModuleObjects\Collections\Description\Document.xml
create ModuleObjects\Collections\Description\ExternalReferences.xml
create ModuleObjects\Collections\JsonForms\IDD_COLLECTIONS.tbjson
create ModuleObjects\Collections\JsonForms\IDD_TD_COLLECTIONS_MAIN.tbjson
create ModuleObjects\Collections\JsonForms\IDD_COLLECTIONS_VIEW.tbjson
create ModuleObjects\Collections\JsonForms\IDD_COLLECTIONS.hjson
create ModuleObjects\Collections\JsonForms\IDD_TD_COLLECTIONS_MAIN.hjson
create ModuleObjects\Collections\JsonForms\IDD_COLLECTIONS_VIEW.hjson
force ModuleObjects\DocumentObjects.xml
force Menu\Comics.menu
No change to package.json was detected. No package manager install will be executed.
This will create the ADMObject inside the ComicsComponents and a document inside the ComicsDocuments and also creates a menu point for the document in the module menu.
<Document>
<Title localizable="true">Collections document</Title>
<Object>Comics.Comics.ComicsDocuments.Collections</Object>
</Document>
When creating the document, in the CPP file, TBLegacy will create some default code, which will use the default primary key f_Code
that you propably didn't use. So your next step should be to open {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\{ModuleName}Documents\D{DocumentName}.cpp
and change the variable names that have been autogenerated.
In the last step, TBLegacy created a menu item for the newly created document.
You can create menu items under {DevEnv_Path}\Standard\Applications\{ApplicationName}\{ModuleName}\Menu\{ModuleName}.menu
.
<!-- Example → Comics menu -->
<?xml version="1.0" encoding="UTF-8"?>
<AppMenu>
<Application name="Comics" image_namespace="Image.Comics.Comics.Images.LogoComicsSmall.png">
<Title localizable="true">Comics description</Title>
<Group name="Comics.Comics">
<Title localizable="true">Comics Module</Title>
<Menu name="ComicsTab">
<Title localizable="true">Comics</Title>
<Menu name="ComicsDocuments">
<Title localizable="true">Comics</Title>
<Document>
<Title localizable="true">Collections</Title>
<Object>Comics.Comics.ComicsDocuments.DCollection</Object>
</Document>
<Document>
<Title localizable="true">Boxes</Title>
<Object>Comics.Comics.ComicsDocuments.DBoxes</Object>
</Document>
<Batch>
<Title localizable="true">Copy Collections</Title>
<Object>Comics.Comics.ComicsDocuments.BDCollectionsCopy</Object>
</Batch>
</Menu>
</Menu>
<Menu name="MangaTab">
<Title localizable="true">Manga</Title>
<Menu name="MangaDocuments">
<Title localizable="true">Manga</Title>
<Document>
<Title localizable="true">Story Arcs</Title>
<Object>Comics.Manga.MangaDocuments.DStoryArcs</Object>
</Document>
</Menu>
</Menu>
</Group>
<Group name="ERP.Preferences" image_namespace="Image.ERP.Core.Images.25x25\Settings.png" insert_after="all">
<Title localizable="true">Preferences</Title>
<Menu name="ComicsOptionsTab">
<Title localizable="true">Comics</Title>
<Menu name="ComicsOptions">
<Title localizable="true">Comics Options</Title>
<Document>
<Title localizable="true">Comics Parameters</Title>
<Object>Comics.Comics.ComicsDocuments.DComicsParameters</Object>
</Document>
</Menu>
</Menu>
</Group>
</Application>
</AppMenu>
In this Example, we created a Mago4 main sidebar menu item, with <Group name="Comics.Comics">
.
You can also extend already existing Groups by referencing the corresponding namespace like with the second group <Group name="ERP.Preferences">
.
Inside the Group
node, the Menu
nodes that host other Menu
nodes will create the tab indexes.
In this example, we would have a "Comics" and a "Manga" index tab, both given a name that would be displayed if there was no Title
node inside.
<!-- Truncated Example → Comics menu -->
<Menu name="ComicsTab">
<Title localizable="true">Comics</Title>
[...]
</Menu>
<Menu name="MangaTab">
<Title localizable="true">Manga</Title>
[...]
</Menu>
The Menu
nodes inside represent the "blocks" in which the documents, reports, etc. are displayed.
You can differ between a <Document>
and a <Batch>
node for "BatchDocuments", special kinds of documents used for processing like copying documents or exports.
Again the <Title>
node can be used to give your document a display name.
But more important is the <Object>
node in which the namespace for the document is defined, like e.g. <Object>Comics.Comics.ComicsDocuments.DCollection</Object>
.
Graphical User Interfaces are described in a JSON
like language.
The files that describe a GUI for a specific document are found in ``{DevEnv_Path}\Standard\Applications{ApplicationName}{ModuleName}\ModuleObjects{DocumentName}\JsonForms`.
In that folder, you'll find .hjson
files, in which you can define the elements that have to be referenced in your code and you'll have the .tbjson
which describe the GUI:
/* Example → Main UI for Comics' Collection document */
{
"id": "IDD_TD_COLLECTIONS_MAIN",
"type": "Tile",
"name": "MainData",
"text": "Collections document",
"child": true,
"items": [
{
"id": "IDC_COLLECTIONS_CODE",
"type": "Edit",
"controlClass": "StringEdit",
"controlCaption": "Code",
"anchor": "COL1",
"captionSize": 3,
"controlSize": 2,
"binding": {
"datasource": "Collections.Code"
},
"tabStop": true,
"width": 48,
"height": 12,
"autoHScroll": true,
"rows": 1,
"multiline": false
},
{
"id": "IDC_COLLECTIONS_DESCRI",
"type": "Edit",
"controlClass": "StringEdit",
"controlCaption": "Description",
"anchor": "COL1",
"captionSize": 3,
"controlSize": 6,
"binding": {
"datasource": "Collections.Description"
},
"tabStop": true,
"width": 154,
"height": 36,
"autoVScroll": true,
"rows": 3,
"multiline": true,
"wantReturn": true
}
],
"hasStaticArea": true,
"width": 654,
"height": 73
}
Since there is no documentation about the tbjson format it is advised to take inspiration from a document that is already in the ERP module and copy the elements from there. [TODO?: Document tbjson more (keywords etc...)]