@netoalmanca/advpl-sensei 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/changelog-generator.md +63 -0
- package/agents/code-generator.md +215 -0
- package/agents/code-reviewer.md +145 -0
- package/agents/debugger.md +83 -0
- package/agents/doc-generator.md +67 -0
- package/agents/docs-reference.md +86 -0
- package/agents/migrator.md +84 -0
- package/agents/process-consultant.md +97 -0
- package/agents/refactorer.md +75 -0
- package/agents/sx-configurator.md +67 -0
- package/commands/changelog.md +66 -0
- package/commands/diagnose.md +67 -0
- package/commands/docs.md +81 -0
- package/commands/document.md +67 -0
- package/commands/explain.md +60 -0
- package/commands/generate.md +111 -0
- package/commands/migrate.md +81 -0
- package/commands/process.md +111 -0
- package/commands/refactor.md +65 -0
- package/commands/review.md +60 -0
- package/commands/sxgen.md +98 -0
- package/commands/test.md +103 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/package.json +30 -0
- package/skills/advpl-code-generation/SKILL.md +163 -0
- package/skills/advpl-code-generation/patterns-fwformbrowse.md +485 -0
- package/skills/advpl-code-generation/patterns-jobs.md +519 -0
- package/skills/advpl-code-generation/patterns-mvc.md +765 -0
- package/skills/advpl-code-generation/patterns-pontos-entrada.md +708 -0
- package/skills/advpl-code-generation/patterns-rest.md +974 -0
- package/skills/advpl-code-generation/patterns-soap.md +639 -0
- package/skills/advpl-code-generation/patterns-treport.md +481 -0
- package/skills/advpl-code-generation/patterns-workflow.md +779 -0
- package/skills/advpl-code-generation/templates-classes.md +1096 -0
- package/skills/advpl-code-review/SKILL.md +72 -0
- package/skills/advpl-code-review/rules-best-practices.md +444 -0
- package/skills/advpl-code-review/rules-modernization.md +290 -0
- package/skills/advpl-code-review/rules-performance.md +333 -0
- package/skills/advpl-code-review/rules-security.md +302 -0
- package/skills/advpl-debugging/SKILL.md +265 -0
- package/skills/advpl-debugging/common-errors.md +1124 -0
- package/skills/advpl-debugging/performance-tips.md +768 -0
- package/skills/advpl-refactoring/SKILL.md +139 -0
- package/skills/advpl-to-tlpp-migration/SKILL.md +293 -0
- package/skills/advpl-to-tlpp-migration/migration-checklist.md +122 -0
- package/skills/advpl-to-tlpp-migration/migration-rules.md +265 -0
- package/skills/changelog-patterns/SKILL.md +99 -0
- package/skills/code-explanation/SKILL.md +66 -0
- package/skills/documentation-patterns/SKILL.md +172 -0
- package/skills/embedded-sql/SKILL.md +379 -0
- package/skills/probat-testing/SKILL.md +226 -0
- package/skills/probat-testing/patterns-unit-tests.md +614 -0
- package/skills/protheus-business/SKILL.md +92 -0
- package/skills/protheus-business/modulo-compras.md +780 -0
- package/skills/protheus-business/modulo-contabilidade.md +874 -0
- package/skills/protheus-business/modulo-estoque.md +876 -0
- package/skills/protheus-business/modulo-faturamento.md +800 -0
- package/skills/protheus-business/modulo-financeiro.md +1015 -0
- package/skills/protheus-business/modulo-fiscal.md +749 -0
- package/skills/protheus-business/modulo-manutencao.md +848 -0
- package/skills/protheus-business/modulo-pcp.md +743 -0
- package/skills/protheus-reference/SKILL.md +119 -0
- package/skills/protheus-reference/native-functions.md +7029 -0
- package/skills/protheus-reference/rest-api-reference.md +1758 -0
- package/skills/protheus-reference/restricted-functions.md +265 -0
- package/skills/protheus-reference/sx-dictionary.md +854 -0
- package/skills/sx-configuration/SKILL.md +184 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: advpl-refactoring
|
|
3
|
+
description: Use when refactoring ADVPL/TLPP code - extract functions, simplify logic, remove dead code, improve naming
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ADVPL/TLPP Refactoring
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Patterns and rules for safe refactoring of ADVPL/TLPP code on TOTVS Protheus. Focuses on improving code structure without changing behavior.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- Functions too long (>100 lines)
|
|
15
|
+
- Duplicated code across files or functions
|
|
16
|
+
- Complex nested conditionals (>3 levels deep)
|
|
17
|
+
- Variables with unclear names
|
|
18
|
+
- Dead code (unreachable blocks, unused variables/functions)
|
|
19
|
+
- God functions that do too many things
|
|
20
|
+
|
|
21
|
+
## Refactoring Patterns
|
|
22
|
+
|
|
23
|
+
### RF-001: Extract Function (Complexity: LOW)
|
|
24
|
+
|
|
25
|
+
**Detect:** Function body > 100 lines with identifiable logical blocks
|
|
26
|
+
**Action:** Extract logical block into a new Static Function
|
|
27
|
+
**Rule:** The extracted function must receive all needed data as parameters (no shared Private/Public)
|
|
28
|
+
|
|
29
|
+
Before:
|
|
30
|
+
```advpl
|
|
31
|
+
User Function ProcessaPedido()
|
|
32
|
+
// ... 40 lines validating data ...
|
|
33
|
+
// ... 30 lines calculating totals ...
|
|
34
|
+
// ... 50 lines saving to database ...
|
|
35
|
+
Return
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
After:
|
|
39
|
+
```advpl
|
|
40
|
+
User Function ProcessaPedido()
|
|
41
|
+
If !fValidaDados(cCodPed)
|
|
42
|
+
Return .F.
|
|
43
|
+
EndIf
|
|
44
|
+
nTotal := fCalculaTotais(cCodPed)
|
|
45
|
+
lOk := fGravaPedido(cCodPed, nTotal)
|
|
46
|
+
Return lOk
|
|
47
|
+
|
|
48
|
+
Static Function fValidaDados(cCodPed)
|
|
49
|
+
// 40 lines
|
|
50
|
+
Return lValido
|
|
51
|
+
|
|
52
|
+
Static Function fCalculaTotais(cCodPed)
|
|
53
|
+
// 30 lines
|
|
54
|
+
Return nTotal
|
|
55
|
+
|
|
56
|
+
Static Function fGravaPedido(cCodPed, nTotal)
|
|
57
|
+
// 50 lines
|
|
58
|
+
Return lOk
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### RF-002: Simplify Conditionals (Complexity: LOW)
|
|
62
|
+
|
|
63
|
+
**Detect:** Nested If > 3 levels deep, or long If/ElseIf chains
|
|
64
|
+
**Action:** Use early return, guard clauses, or Do Case
|
|
65
|
+
|
|
66
|
+
Before:
|
|
67
|
+
```advpl
|
|
68
|
+
If lCondicao1
|
|
69
|
+
If lCondicao2
|
|
70
|
+
If lCondicao3
|
|
71
|
+
// codigo principal
|
|
72
|
+
EndIf
|
|
73
|
+
EndIf
|
|
74
|
+
EndIf
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
After:
|
|
78
|
+
```advpl
|
|
79
|
+
If !lCondicao1
|
|
80
|
+
Return
|
|
81
|
+
EndIf
|
|
82
|
+
If !lCondicao2
|
|
83
|
+
Return
|
|
84
|
+
EndIf
|
|
85
|
+
If !lCondicao3
|
|
86
|
+
Return
|
|
87
|
+
EndIf
|
|
88
|
+
// codigo principal
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### RF-003: Remove Dead Code (Complexity: LOW)
|
|
92
|
+
|
|
93
|
+
**Detect:** Variables declared but never used, unreachable code after Return, commented-out blocks
|
|
94
|
+
**Action:** Remove the dead code entirely
|
|
95
|
+
**Rule:** Use Grep to verify the variable/function is not called from other files before removing
|
|
96
|
+
|
|
97
|
+
### RF-004: Improve Naming (Complexity: LOW)
|
|
98
|
+
|
|
99
|
+
**Detect:** Variables without Hungarian notation, single-letter names (except loop counters), unclear names
|
|
100
|
+
**Action:** Rename following Hungarian notation convention
|
|
101
|
+
|
|
102
|
+
| Type | Prefix | Example |
|
|
103
|
+
|------|--------|---------|
|
|
104
|
+
| Character | c | cNomeCli, cCodProd |
|
|
105
|
+
| Numeric | n | nValor, nQtde |
|
|
106
|
+
| Logical | l | lOk, lContinua |
|
|
107
|
+
| Date | d | dDataIni, dEmissao |
|
|
108
|
+
| Array | a | aDados, aItens |
|
|
109
|
+
| Object | o | oModel, oReport |
|
|
110
|
+
| Block | b | bBloco, bFiltro |
|
|
111
|
+
|
|
112
|
+
### RF-005: Eliminate Duplication (Complexity: MEDIUM)
|
|
113
|
+
|
|
114
|
+
**Detect:** Two or more code blocks with >5 similar lines
|
|
115
|
+
**Action:** Extract common logic into a shared function
|
|
116
|
+
**Rule:** Only extract if the logic is truly identical, not just visually similar
|
|
117
|
+
|
|
118
|
+
### RF-006: Reduce Function Parameters (Complexity: MEDIUM)
|
|
119
|
+
|
|
120
|
+
**Detect:** Functions with >5 parameters
|
|
121
|
+
**Action:** Group related parameters into a JSON object or array
|
|
122
|
+
**Rule:** Only apply if parameters are logically related
|
|
123
|
+
|
|
124
|
+
## Refactoring Process
|
|
125
|
+
|
|
126
|
+
1. **Analyze** — Read the file, identify refactoring opportunities
|
|
127
|
+
2. **Prioritize** — Order by impact: dead code removal first, then naming, then extraction
|
|
128
|
+
3. **Present plan** — Show each refactoring with before/after
|
|
129
|
+
4. **Wait for approval** — User must approve before changes are applied
|
|
130
|
+
5. **Apply changes** — One refactoring at a time
|
|
131
|
+
6. **Verify** — Ensure the code structure is correct after each change
|
|
132
|
+
|
|
133
|
+
## Safety Rules
|
|
134
|
+
|
|
135
|
+
- NEVER change business logic during refactoring
|
|
136
|
+
- NEVER rename Public/Private variables that might be used externally
|
|
137
|
+
- ALWAYS check for external callers before removing functions (use Grep)
|
|
138
|
+
- ALWAYS preserve the function signature (parameters and return type)
|
|
139
|
+
- If unsure whether behavior will change, DO NOT refactor — flag it as a suggestion only
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: advpl-to-tlpp-migration
|
|
3
|
+
description: Use when migrating ADVPL procedural code to TLPP object-oriented code, converting functions to classes, or modernizing legacy Protheus code
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ADVPL to TLPP Migration
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Systematic approach for converting legacy ADVPL procedural code to modern TLPP with object-oriented programming patterns. This skill guides the migration process from `.prw` files with User Functions and Static Functions to `.tlpp` files with namespaces, classes, and methods -- while preserving backward compatibility with existing callers.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- Converting procedural ADVPL functions to TLPP classes
|
|
15
|
+
- Refactoring User Functions into object-oriented service classes
|
|
16
|
+
- Replacing Private/Public variable scoping with class properties
|
|
17
|
+
- Modernizing multiple `#Include` directives to TLPP `.th` includes (`tlpp-core.th`, `tlpp-rest.th`, etc.) and adding proper `namespace` declarations
|
|
18
|
+
- Migrating Static Functions to private class methods
|
|
19
|
+
- Wrapping legacy function calls for backward compatibility during gradual migration
|
|
20
|
+
- Any `.prw` to `.tlpp` file conversion
|
|
21
|
+
|
|
22
|
+
## Migration Strategy
|
|
23
|
+
|
|
24
|
+
```dot
|
|
25
|
+
digraph migration {
|
|
26
|
+
rankdir=TB;
|
|
27
|
+
node [shape=box];
|
|
28
|
+
|
|
29
|
+
analyze [label="Analyze source .prw file"];
|
|
30
|
+
identify [label="Identify functions\nand dependencies"];
|
|
31
|
+
map [label="Map to class structure\n(properties, methods, constructor)"];
|
|
32
|
+
approve [label="User approves\nclass design?" shape=diamond];
|
|
33
|
+
generate [label="Generate .tlpp file\nwith namespace and class"];
|
|
34
|
+
checklist [label="Run migration checklist\n(migration-checklist.md)"];
|
|
35
|
+
validate [label="Validate compilation\nand caller compatibility"];
|
|
36
|
+
|
|
37
|
+
analyze -> identify;
|
|
38
|
+
identify -> map;
|
|
39
|
+
map -> approve;
|
|
40
|
+
approve -> generate [label="yes"];
|
|
41
|
+
approve -> map [label="no - revise"];
|
|
42
|
+
generate -> checklist;
|
|
43
|
+
checklist -> validate;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
1. **Analyze** the source `.prw` file to understand all functions, variables, and external dependencies
|
|
48
|
+
2. **Identify** each User Function and Static Function, their parameters, and shared state
|
|
49
|
+
3. **Map** functions to a class structure -- methods, properties, constructor parameters
|
|
50
|
+
4. **User approves** the proposed class design before code generation
|
|
51
|
+
5. **Generate** the `.tlpp` file with proper namespace, class definition, and method implementations
|
|
52
|
+
6. **Run checklist** from `migration-checklist.md` to verify completeness
|
|
53
|
+
7. **Validate** that the code compiles and all existing callers still work
|
|
54
|
+
|
|
55
|
+
## Core Conversion Rules
|
|
56
|
+
|
|
57
|
+
| ADVPL Construct | TLPP Equivalent | Notes |
|
|
58
|
+
|----------------|-----------------|-------|
|
|
59
|
+
| `#Include "TOTVS.CH"` | `#Include "tlpp-core.th"` | Use the TLPP-specific includes (`.th` files); `Protheus.ch` is obsolete. Do NOT add `using namespace tlpp.core`, `tlpp.rest`, or `tlpp.log` -- use the `.th` includes instead |
|
|
60
|
+
| `User Function Name()` | `namespace custom.module.service; class NameService; method execute()` | Main entry point becomes the primary public method. See namespace conventions below |
|
|
61
|
+
| `Static Function Helper()` | `method helper() as private` | Internal functions become private methods |
|
|
62
|
+
| `Private cVar := "x"` | `data cVar as character` (class property) | Private variables become class-level data declarations |
|
|
63
|
+
| `Public nGlobal` | Remove -- pass via constructor/parameters | Public variables must be eliminated entirely |
|
|
64
|
+
| `Local aArray := {}` | Unchanged inside methods | Local variables remain as-is within method bodies |
|
|
65
|
+
|
|
66
|
+
See `migration-rules.md` for the complete mapping reference covering preprocessor directives, database operations, error handling, and UI elements.
|
|
67
|
+
|
|
68
|
+
## TLPP Naming Conventions (Official TOTVS Standard)
|
|
69
|
+
|
|
70
|
+
Follow the official TOTVS naming conventions from TDN (https://tdn.totvs.com/pages/releaseview.action?pageId=633537898).
|
|
71
|
+
|
|
72
|
+
### Namespaces
|
|
73
|
+
|
|
74
|
+
All names must be **lowercase**, separated by **dots**, with **no underscores**.
|
|
75
|
+
|
|
76
|
+
**For TOTVS product code:**
|
|
77
|
+
```
|
|
78
|
+
totvs.protheus.<segmento>.<agrupador/servico>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Available segments: agrobusiness, backoffice, construction, distribution, educational, financial, health, hospitality, legal, manufacturing, retail, services
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
- `totvs.protheus.backoffice.customer`
|
|
85
|
+
- `totvs.protheus.backoffice.supplier`
|
|
86
|
+
- `totvs.protheus.financial.payment.receive`
|
|
87
|
+
- `totvs.protheus.manufacturing.material.balance`
|
|
88
|
+
|
|
89
|
+
Exceptions: Framework team uses `framework`, Protheus Engineering uses `software.engineering`.
|
|
90
|
+
|
|
91
|
+
**For client customizations (most common in migrations):**
|
|
92
|
+
```
|
|
93
|
+
custom.<agrupador>.<servico>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Start with `custom.`, the rest is free. Examples:
|
|
97
|
+
- `custom.cadastros.cliente`
|
|
98
|
+
- `custom.relatorios.customizados`
|
|
99
|
+
- `custom.faturamento.pedido`
|
|
100
|
+
|
|
101
|
+
### File Naming
|
|
102
|
+
|
|
103
|
+
**For TOTVS product:** `<segmento>.<agrupador/servico>.<funcionalidade>.tlpp`
|
|
104
|
+
- Examples: `backoffice.tgv.contact.controller.tlpp`, `financial.payment.receive.tlpp`
|
|
105
|
+
|
|
106
|
+
**For client customizations:** `custom.<agrupador>.<funcionalidade>.tlpp`
|
|
107
|
+
- Examples: `custom.cadastros.cliente.tlpp`, `custom.ma030inc.tlpp`
|
|
108
|
+
|
|
109
|
+
### Classes, Functions, and Methods
|
|
110
|
+
|
|
111
|
+
| Element | Convention | Example |
|
|
112
|
+
|---------|-----------|---------|
|
|
113
|
+
| Classes | **PascalCase** | `ContactsController`, `PedidoService` |
|
|
114
|
+
| Functions | **camelCase** | `contactsController()`, `calcTotal()` |
|
|
115
|
+
| Methods | **camelCase** | `validName()`, `processOrder()` |
|
|
116
|
+
|
|
117
|
+
**No underscores** in any identifier.
|
|
118
|
+
|
|
119
|
+
### Deciding the Namespace
|
|
120
|
+
|
|
121
|
+
When migrating, ask the user if the code is:
|
|
122
|
+
1. **TOTVS product code** -> use `totvs.protheus.<segmento>.<agrupador>`
|
|
123
|
+
2. **Client customization** -> use `custom.<agrupador>.<servico>` (this is the most common case)
|
|
124
|
+
|
|
125
|
+
If the user does not specify, default to `custom.<module>.<service>` pattern.
|
|
126
|
+
|
|
127
|
+
## Before/After Example
|
|
128
|
+
|
|
129
|
+
### Before (ADVPL Procedural) -- `CalcPed.prw`
|
|
130
|
+
|
|
131
|
+
```advpl
|
|
132
|
+
#Include "TOTVS.CH"
|
|
133
|
+
#Include "TopConn.ch"
|
|
134
|
+
|
|
135
|
+
/*/{Protheus.doc} CalcPed
|
|
136
|
+
Calcula o total de um pedido de venda
|
|
137
|
+
@type User Function
|
|
138
|
+
@author Dev
|
|
139
|
+
@since 01/01/2024
|
|
140
|
+
@param cPedido, Caractere, Numero do pedido
|
|
141
|
+
@return nTotal, Numerico, Valor total do pedido
|
|
142
|
+
/*/
|
|
143
|
+
User Function CalcPed(cPedido)
|
|
144
|
+
Local nTotal := 0
|
|
145
|
+
Private cAliasPed := "SC5"
|
|
146
|
+
Private cAliasItens := "SC6"
|
|
147
|
+
|
|
148
|
+
Local aArea := GetArea()
|
|
149
|
+
|
|
150
|
+
Begin Sequence
|
|
151
|
+
|
|
152
|
+
DbSelectArea(cAliasPed)
|
|
153
|
+
DbSetOrder(1)
|
|
154
|
+
|
|
155
|
+
If !DbSeek(xFilial(cAliasPed) + cPedido)
|
|
156
|
+
Conout("Pedido nao encontrado: " + cPedido)
|
|
157
|
+
Break
|
|
158
|
+
EndIf
|
|
159
|
+
|
|
160
|
+
nTotal := fCalcTotal(cPedido)
|
|
161
|
+
|
|
162
|
+
Recover Using oError
|
|
163
|
+
Conout("Erro em CalcPed: " + oError:Description)
|
|
164
|
+
nTotal := 0
|
|
165
|
+
End Sequence
|
|
166
|
+
|
|
167
|
+
RestArea(aArea)
|
|
168
|
+
Return nTotal
|
|
169
|
+
|
|
170
|
+
Static Function fCalcTotal(cPedido)
|
|
171
|
+
Local nSoma := 0
|
|
172
|
+
|
|
173
|
+
DbSelectArea(cAliasItens)
|
|
174
|
+
DbSetOrder(1)
|
|
175
|
+
|
|
176
|
+
DbSeek(xFilial(cAliasItens) + cPedido)
|
|
177
|
+
While !Eof() .And. SC6->C6_NUM == cPedido
|
|
178
|
+
nSoma += SC6->C6_VALOR * SC6->C6_QTDVEN
|
|
179
|
+
DbSkip()
|
|
180
|
+
EndDo
|
|
181
|
+
|
|
182
|
+
Return nSoma
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### After (TLPP Object-Oriented) -- `custom.faturamento.pedido.tlpp`
|
|
186
|
+
|
|
187
|
+
```tlpp
|
|
188
|
+
#Include "tlpp-core.th"
|
|
189
|
+
|
|
190
|
+
namespace custom.faturamento.pedido
|
|
191
|
+
|
|
192
|
+
class PedidoService
|
|
193
|
+
|
|
194
|
+
data cAliasPed as character
|
|
195
|
+
data cAliasItens as character
|
|
196
|
+
|
|
197
|
+
public method new() as object
|
|
198
|
+
public method calcTotal(cPedido as character) as numeric
|
|
199
|
+
private method somaItens(cPedido as character) as numeric
|
|
200
|
+
|
|
201
|
+
endclass
|
|
202
|
+
|
|
203
|
+
method new() class PedidoService
|
|
204
|
+
::cAliasPed := "SC5"
|
|
205
|
+
::cAliasItens := "SC6"
|
|
206
|
+
return self
|
|
207
|
+
|
|
208
|
+
method calcTotal(cPedido as character) class PedidoService
|
|
209
|
+
local nTotal := 0
|
|
210
|
+
local aArea := GetArea()
|
|
211
|
+
|
|
212
|
+
begin sequence
|
|
213
|
+
|
|
214
|
+
DbSelectArea(::cAliasPed)
|
|
215
|
+
DbSetOrder(1)
|
|
216
|
+
|
|
217
|
+
if !DbSeek(xFilial(::cAliasPed) + cPedido)
|
|
218
|
+
FWLogMsg("WARN", , "PedidoService", "calcTotal", , , ;
|
|
219
|
+
"Pedido nao encontrado: " + cPedido)
|
|
220
|
+
break
|
|
221
|
+
endif
|
|
222
|
+
|
|
223
|
+
nTotal := ::somaItens(cPedido)
|
|
224
|
+
|
|
225
|
+
recover using oError
|
|
226
|
+
FWLogMsg("ERROR", , "PedidoService", "calcTotal", , , ;
|
|
227
|
+
"Erro: " + oError:Description)
|
|
228
|
+
nTotal := 0
|
|
229
|
+
end sequence
|
|
230
|
+
|
|
231
|
+
RestArea(aArea)
|
|
232
|
+
return nTotal
|
|
233
|
+
|
|
234
|
+
method somaItens(cPedido as character) class PedidoService
|
|
235
|
+
local nSoma := 0
|
|
236
|
+
|
|
237
|
+
DbSelectArea(::cAliasItens)
|
|
238
|
+
DbSetOrder(1)
|
|
239
|
+
|
|
240
|
+
DbSeek(xFilial(::cAliasItens) + cPedido)
|
|
241
|
+
while !Eof() .And. (::cAliasItens)->(C6_NUM) == cPedido
|
|
242
|
+
nSoma += (::cAliasItens)->(C6_VALOR) * (::cAliasItens)->(C6_QTDVEN)
|
|
243
|
+
DbSkip()
|
|
244
|
+
enddo
|
|
245
|
+
|
|
246
|
+
return nSoma
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Backward Compatibility Wrapper -- `CalcPed.prw` (preserved)
|
|
250
|
+
|
|
251
|
+
```advpl
|
|
252
|
+
#Include "TOTVS.CH"
|
|
253
|
+
|
|
254
|
+
/*/{Protheus.doc} CalcPed
|
|
255
|
+
Wrapper de compatibilidade - delega para PedidoService (TLPP)
|
|
256
|
+
@type User Function
|
|
257
|
+
@author Dev
|
|
258
|
+
@since 01/01/2024
|
|
259
|
+
@param cPedido, Caractere, Numero do pedido
|
|
260
|
+
@return nTotal, Numerico, Valor total do pedido
|
|
261
|
+
/*/
|
|
262
|
+
User Function CalcPed(cPedido)
|
|
263
|
+
Local oService := custom.faturamento.pedido.PedidoService():new()
|
|
264
|
+
Return oService:calcTotal(cPedido)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Key Migration Decisions
|
|
268
|
+
|
|
269
|
+
| Decision | Guideline |
|
|
270
|
+
|----------|-----------|
|
|
271
|
+
| One class per file | Each `.tlpp` file should contain a single class with a clear responsibility |
|
|
272
|
+
| Namespace = official TOTVS convention | For customizations use `custom.<agrupador>.<servico>` (e.g., `custom.faturamento.pedido`). For TOTVS product use `totvs.protheus.<segmento>.<agrupador>`. All lowercase, no underscores, separated by dots |
|
|
273
|
+
| User Function preserved as wrapper | Keep the original `.prw` User Function as a thin wrapper that delegates to the new class |
|
|
274
|
+
| Gradual migration | Migrate one function group at a time; wrappers ensure existing callers are not broken |
|
|
275
|
+
| Constructor for shared state | Values that were previously `Private`/`Public` variables shared across functions should be passed through the constructor or set as class properties |
|
|
276
|
+
| Logging over Conout | Prefer `FWLogMsg()` or `FWLogError()` over raw `Conout()` in TLPP classes |
|
|
277
|
+
|
|
278
|
+
## Common Mistakes
|
|
279
|
+
|
|
280
|
+
| Mistake | Consequence | Fix |
|
|
281
|
+
|---------|-------------|-----|
|
|
282
|
+
| Removing User Function without wrapper | Breaks all external callers (`u_FuncName`) | Always keep a `.prw` wrapper during migration |
|
|
283
|
+
| Using `Private` variables inside methods | Variables leak to called methods unexpectedly | Convert to class `data` properties or `Local` variables |
|
|
284
|
+
| Forgetting `::` prefix for class properties | References undefined local variable instead of property | Always use `::propertyName` inside methods |
|
|
285
|
+
| Putting multiple classes in one `.tlpp` file | Hard to maintain, namespace confusion | One class per file |
|
|
286
|
+
| Not preserving `GetArea()`/`RestArea()` | Database cursor state corrupted for callers | Always save and restore area in methods that access DB |
|
|
287
|
+
| Skipping `xFilial()` after migration | Multi-branch queries return wrong data | Always use `xFilial(cAlias)` in `DbSeek` operations |
|
|
288
|
+
| Ignoring Static variables used across functions | Shared state lost when functions become methods | Convert `Static` variables to class `data` properties |
|
|
289
|
+
|
|
290
|
+
## References
|
|
291
|
+
|
|
292
|
+
- `migration-rules.md` -- Complete mapping of all ADVPL constructs to TLPP equivalents
|
|
293
|
+
- `migration-checklist.md` -- Step-by-step checklist for executing and validating a migration
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# ADVPL to TLPP Migration Checklist
|
|
2
|
+
|
|
3
|
+
Use this checklist for every migration from procedural ADVPL (`.prw`) to object-oriented TLPP (`.tlpp`). Complete each section in order.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Pre-Migration Analysis
|
|
8
|
+
|
|
9
|
+
Perform this analysis before writing any TLPP code.
|
|
10
|
+
|
|
11
|
+
- [ ] Identify all `User Function` definitions in the source `.prw` file
|
|
12
|
+
- [ ] Identify all `Static Function` definitions in the source `.prw` file
|
|
13
|
+
- [ ] Map function call dependencies (which functions call which)
|
|
14
|
+
- [ ] Identify `Private` variables shared across multiple functions
|
|
15
|
+
- [ ] Identify `Public` variables and all locations where they are read/written
|
|
16
|
+
- [ ] Identify `Static` file-level variables and their usage patterns
|
|
17
|
+
- [ ] List all external callers of each `User Function` (other `.prw` files, menus, jobs, schedules)
|
|
18
|
+
- [ ] Identify all database aliases used (`DbSelectArea`, `RecLock`, direct alias references)
|
|
19
|
+
- [ ] Document all `#Include` directives (they will be replaced by TLPP `.th` includes: `tlpp-core.th`, `tlpp-rest.th`, etc.)
|
|
20
|
+
- [ ] Identify any code blocks (`{|| ...}`) that reference `Private`/`Static` variables
|
|
21
|
+
- [ ] Check for `MV_*` parameter usage (`GetMV`, `SuperGetMV`) that may need class-level access
|
|
22
|
+
- [ ] Note any UI elements (dialogs, buttons, gets) that will need a separate View class
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 2. Migration Execution
|
|
27
|
+
|
|
28
|
+
Create the TLPP class structure and convert all functions.
|
|
29
|
+
|
|
30
|
+
### Namespace and File Setup
|
|
31
|
+
|
|
32
|
+
- [ ] Define the namespace following TOTVS convention: `custom.<agrupador>.<servico>` for customizations or `totvs.protheus.<segmento>.<agrupador>` for product code (all lowercase, dots, no underscores)
|
|
33
|
+
- [ ] Create the `.tlpp` file with one class per file, named following convention: `custom.<agrupador>.<funcionalidade>.tlpp`
|
|
34
|
+
- [ ] Add `#Include "tlpp-core.th"` at the top of the file (and `tlpp-rest.th` if using REST annotations)
|
|
35
|
+
|
|
36
|
+
### Class Skeleton
|
|
37
|
+
|
|
38
|
+
- [ ] Define the class name using PascalCase with a purpose suffix (e.g., `PedidoService`, `ClienteRepository`)
|
|
39
|
+
- [ ] Declare all `data` properties (converted from `Private`/`Static` variables) with `as <type>`
|
|
40
|
+
- [ ] Declare all `public method` signatures (from `User Function` conversions)
|
|
41
|
+
- [ ] Declare all `private method` signatures (from `Static Function` conversions)
|
|
42
|
+
- [ ] Add `endclass` at the end of the class definition
|
|
43
|
+
|
|
44
|
+
### Constructor
|
|
45
|
+
|
|
46
|
+
- [ ] Create `method new()` that initializes all class properties
|
|
47
|
+
- [ ] Move any values that were `Public` variables into constructor parameters
|
|
48
|
+
- [ ] Set default values for properties that had default `Private` variable values
|
|
49
|
+
- [ ] Return `self` from the constructor
|
|
50
|
+
|
|
51
|
+
### Convert Functions to Methods
|
|
52
|
+
|
|
53
|
+
- [ ] Convert each `User Function` to a `public method` with proper parameter typing (`as character`, `as numeric`, etc.)
|
|
54
|
+
- [ ] Convert each `Static Function` to a `private method`
|
|
55
|
+
- [ ] Replace all references to `Private` variables with `::propertyName`
|
|
56
|
+
- [ ] Replace all calls to `Static Function Helper()` with `::helper()`
|
|
57
|
+
- [ ] Ensure every method that accesses the database calls `GetArea()` at the start and `RestArea()` before returning
|
|
58
|
+
- [ ] Replace `Conout()` logging with `FWLogMsg()` where appropriate
|
|
59
|
+
- [ ] Verify that `xFilial(cAlias)` is used in all `DbSeek` operations
|
|
60
|
+
|
|
61
|
+
### Update Includes (in the `.tlpp` file)
|
|
62
|
+
|
|
63
|
+
- [ ] Replace ADVPL `.ch` includes with TLPP `.th` includes: `#Include "tlpp-core.th"` (main), `#Include "tlpp-rest.th"` (REST annotations), `#Include "tlpp-object.th"` (advanced objects)
|
|
64
|
+
- [ ] Add the `namespace` declaration for the project (e.g., `namespace custom.faturamento.pedido`)
|
|
65
|
+
- [ ] Do NOT add `using namespace tlpp.core`, `tlpp.log`, `tlpp.rest`, `tlpp.data`, etc. -- these are NOT needed; use the `.th` includes instead
|
|
66
|
+
|
|
67
|
+
### Backward Compatibility Wrapper (`.prw` file — uses `#Include "TOTVS.CH"`)
|
|
68
|
+
|
|
69
|
+
- [ ] Create or update the `.prw` wrapper file that preserves the original `User Function` name
|
|
70
|
+
- [ ] The wrapper must instantiate the TLPP class and delegate to the appropriate method
|
|
71
|
+
- [ ] Verify the wrapper passes all original parameters correctly
|
|
72
|
+
- [ ] Verify the wrapper returns the same type as the original function
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 3. Post-Migration Validation
|
|
77
|
+
|
|
78
|
+
Verify that the migration is complete and correct.
|
|
79
|
+
|
|
80
|
+
### Compilation
|
|
81
|
+
|
|
82
|
+
- [ ] The `.tlpp` file compiles without errors
|
|
83
|
+
- [ ] The `.prw` wrapper file compiles without errors
|
|
84
|
+
- [ ] No warnings related to undefined variables or methods
|
|
85
|
+
|
|
86
|
+
### Functional Validation
|
|
87
|
+
|
|
88
|
+
- [ ] All external callers (other functions, menus, jobs) work correctly through the wrapper
|
|
89
|
+
- [ ] Database operations produce the same results as the original code
|
|
90
|
+
- [ ] Record locking and unlocking (`RecLock` / `MsUnlock`) work correctly
|
|
91
|
+
- [ ] Error handling (`Begin Sequence` / `Recover`) catches and reports errors correctly
|
|
92
|
+
- [ ] Return values match the original function's return type and behavior
|
|
93
|
+
|
|
94
|
+
### Code Quality
|
|
95
|
+
|
|
96
|
+
- [ ] No `Private` or `Public` variable declarations remain in the `.tlpp` file
|
|
97
|
+
- [ ] No leaked variables -- all variables are either `Local`, `data`, or `static data`
|
|
98
|
+
- [ ] Class properties use correct Hungarian notation prefixes (`cName`, `nValue`, `lFlag`, `aList`, `oObj`)
|
|
99
|
+
- [ ] Method names follow camelCase convention
|
|
100
|
+
- [ ] Class name follows PascalCase convention
|
|
101
|
+
- [ ] Namespace follows TOTVS convention (`custom.<agrupador>.<servico>` or `totvs.protheus.<segmento>.<agrupador>`)
|
|
102
|
+
- [ ] One class per `.tlpp` file
|
|
103
|
+
- [ ] All `GetArea()` calls have matching `RestArea()` calls (no area leaks)
|
|
104
|
+
- [ ] Code blocks that reference class state use `self` explicitly when evaluated externally
|
|
105
|
+
|
|
106
|
+
### Documentation
|
|
107
|
+
|
|
108
|
+
- [ ] Class-level `Protheus.doc` comment block is present with `@type class`
|
|
109
|
+
- [ ] Each public method has a `Protheus.doc` comment block with `@param` and `@return`
|
|
110
|
+
- [ ] The wrapper `.prw` file documents that it delegates to the TLPP class
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Quick Reference: File Checklist per Migration
|
|
115
|
+
|
|
116
|
+
For each `.prw` file migrated, you should end up with:
|
|
117
|
+
|
|
118
|
+
| File | Purpose | Status |
|
|
119
|
+
|------|---------|--------|
|
|
120
|
+
| `ClassName.tlpp` | New TLPP class with all logic | - [ ] Created |
|
|
121
|
+
| `OriginalName.prw` | Wrapper preserving `User Function` signature | - [ ] Updated |
|
|
122
|
+
| Original `.prw` | Archived or removed after full rollout | - [ ] Handled |
|