http-sankhya 1.0.3 → 1.0.5
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/README.md +145 -7
- package/dist/Sankhya.d.ts +43 -1
- package/dist/Sankhya.js +57 -4
- package/dist/SankhyaHelper.d.ts +16 -0
- package/dist/SankhyaHelper.js +77 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ await sankhya.login();
|
|
|
44
44
|
|
|
45
45
|
### 1. loadRecords (Buscar Múltiplos Registros)
|
|
46
46
|
|
|
47
|
-
Busca uma lista de registros com suporte a filtros, paginação e seleção de campos.
|
|
47
|
+
Busca uma lista de registros com suporte a filtros, paginação e seleção de campos. Este método utiliza o serviço `CRUDServiceProvider.loadRecords`.
|
|
48
48
|
|
|
49
49
|
#### Exemplo Básico
|
|
50
50
|
```typescript
|
|
@@ -54,6 +54,12 @@ const produtos = await sankhya.loadRecords({
|
|
|
54
54
|
expression: "ATIVO = 'S'" // Filtro SQL-like
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
// Retorno Exemplo:
|
|
59
|
+
// [
|
|
60
|
+
// { "CODGRUPOPROD": "100", "DESCRGRUPOPROD": "GERAL", "ATIVO": "S" },
|
|
61
|
+
// { "CODGRUPOPROD": "101", "DESCRGRUPOPROD": "MATERIA PRIMA", "ATIVO": "S" }
|
|
62
|
+
// ]
|
|
57
63
|
```
|
|
58
64
|
|
|
59
65
|
#### Exemplo com Paginação e Seleção de Campos
|
|
@@ -72,6 +78,12 @@ const parceiros = await sankhya.loadRecords({
|
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
});
|
|
81
|
+
|
|
82
|
+
// Retorno Exemplo:
|
|
83
|
+
// [
|
|
84
|
+
// { "CODPARC": "200", "NOMEPARC": "CLIENTE EXEMPLO", "CGC_CPF": "123.456.789-00", "EMAIL": "cliente@email.com" },
|
|
85
|
+
// { "CODPARC": "201", "NOMEPARC": "OUTRO CLIENTE", "CGC_CPF": "987.654.321-00", "EMAIL": "outro@email.com" }
|
|
86
|
+
// ]
|
|
75
87
|
```
|
|
76
88
|
|
|
77
89
|
#### Exemplo com Campos de Apresentação
|
|
@@ -85,13 +97,23 @@ const vendas = await sankhya.loadRecords({
|
|
|
85
97
|
expression: "DTNEG >= '01/01/2024'"
|
|
86
98
|
}
|
|
87
99
|
});
|
|
100
|
+
|
|
101
|
+
// Retorno Exemplo:
|
|
102
|
+
// [
|
|
103
|
+
// {
|
|
104
|
+
// "NUNOTA": "100",
|
|
105
|
+
// "DTNEG": "01/01/2024",
|
|
106
|
+
// "CODPARC": "200",
|
|
107
|
+
// "Parceiro_NOMEPARC": "CLIENTE EXEMPLO"
|
|
108
|
+
// }
|
|
109
|
+
// ]
|
|
88
110
|
```
|
|
89
111
|
|
|
90
112
|
---
|
|
91
113
|
|
|
92
114
|
### 2. loadRecord (Buscar Registro Único)
|
|
93
115
|
|
|
94
|
-
Busca um único registro específico, geralmente pela Chave Primária (PK).
|
|
116
|
+
Busca um único registro específico, geralmente pela Chave Primária (PK). Este método utiliza o serviço `CRUDServiceProvider.loadRecord`.
|
|
95
117
|
|
|
96
118
|
```typescript
|
|
97
119
|
const produto = await sankhya.loadRecord({
|
|
@@ -110,13 +132,21 @@ const produto = await sankhya.loadRecord({
|
|
|
110
132
|
|
|
111
133
|
console.log(produto);
|
|
112
134
|
// Saída: { CODPROD: "1005", DESCRPROD: "PRODUTO TESTE", ... }
|
|
135
|
+
|
|
136
|
+
// Retorno Exemplo Completo:
|
|
137
|
+
// {
|
|
138
|
+
// "CODPROD": "1005",
|
|
139
|
+
// "DESCRPROD": "PRODUTO TESTE",
|
|
140
|
+
// "ATIVO": "S",
|
|
141
|
+
// "PRECO": "50.00"
|
|
142
|
+
// }
|
|
113
143
|
```
|
|
114
144
|
|
|
115
145
|
---
|
|
116
146
|
|
|
117
147
|
### 3. saveRecord (Criar ou Atualizar Registro)
|
|
118
148
|
|
|
119
|
-
Cria ou atualiza registros. A biblioteca formata automaticamente o payload do objeto `localFields` para o padrão exigido pelo Sankhya.
|
|
149
|
+
Cria ou atualiza registros. Este método é específico para manipulações que utilizam o serviço `CRUDServiceProvider.saveRecord`. A biblioteca formata automaticamente o payload do objeto `localFields` para o padrão exigido pelo Sankhya.
|
|
120
150
|
|
|
121
151
|
#### Criar Novo Registro
|
|
122
152
|
Para criar, omita a Chave Primária (se for auto-incremental) ou passe os valores necessários.
|
|
@@ -136,6 +166,12 @@ const novoGrupo = await sankhya.saveRecord({
|
|
|
136
166
|
}
|
|
137
167
|
}
|
|
138
168
|
});
|
|
169
|
+
|
|
170
|
+
// Retorno Exemplo:
|
|
171
|
+
// {
|
|
172
|
+
// "CODGRUPOPROD": "161000",
|
|
173
|
+
// "DESCRGRUPOPROD": "NOVO GRUPO 2024"
|
|
174
|
+
// }
|
|
139
175
|
```
|
|
140
176
|
|
|
141
177
|
#### Atualizar Registro Existente
|
|
@@ -152,17 +188,41 @@ const atualizacao = await sankhya.saveRecord({
|
|
|
152
188
|
CODGRUPOPROD: "20310006" // Chave Primária (PK) para identificação do registro
|
|
153
189
|
}
|
|
154
190
|
});
|
|
191
|
+
|
|
192
|
+
#### Retorno Exemplo (Sucesso)
|
|
193
|
+
Tanto na criação quanto na atualização, a biblioteca processa a resposta e retorna um objeto limpo com os campos solicitados no `fieldset`.
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"CODGRUPOPROD": "160700",
|
|
198
|
+
"DESCRGRUPOPROD": "NOME ATUALIZADO",
|
|
199
|
+
"ATIVO": "N"
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### Retorno Exemplo (Falha)
|
|
204
|
+
Caso ocorra algum erro (status '0'), a biblioteca retorna o objeto de resposta original contendo a mensagem de erro.
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"serviceName": "CRUDServiceProvider.saveRecord",
|
|
209
|
+
"status": "0",
|
|
210
|
+
"pendingPrinting": "false",
|
|
211
|
+
"transactionId": "123456789",
|
|
212
|
+
"statusMessage": "Erro: O registro já existe ou violação de restrição de integridade."
|
|
213
|
+
}
|
|
214
|
+
```
|
|
155
215
|
```
|
|
156
216
|
|
|
157
217
|
---
|
|
158
218
|
|
|
159
|
-
### 4. Execução de Serviço
|
|
219
|
+
### 4. Execução de Serviço Mge (execServiceMge)
|
|
160
220
|
|
|
161
|
-
Para endpoints que não sejam CRUD padrão (ex: executar Stored Procedures, ações de workflow, ou consultas de metadados), use `
|
|
221
|
+
Para endpoints que não sejam CRUD padrão (ex: executar Stored Procedures, ações de workflow, ou consultas de metadados), use `execServiceMge`. Este método utiliza o endpoint `/gateway/v1/mge/service.sbr`.
|
|
162
222
|
|
|
163
223
|
#### Exemplo: Consultar Estoque (Serviço Hipotético)
|
|
164
224
|
```typescript
|
|
165
|
-
const estoque = await sankhya.
|
|
225
|
+
const estoque = await sankhya.execServiceMge({
|
|
166
226
|
serviceName: 'EstoqueSP.getEstoque',
|
|
167
227
|
requestBody: {
|
|
168
228
|
codProd: '1005',
|
|
@@ -175,7 +235,7 @@ const estoque = await sankhya.execService({
|
|
|
175
235
|
Embora exista o método `.delete()`, algumas operações de exclusão no Sankhya são feitas via serviços específicos.
|
|
176
236
|
|
|
177
237
|
```typescript
|
|
178
|
-
await sankhya.
|
|
238
|
+
await sankhya.execServiceMge({
|
|
179
239
|
serviceName: 'CRUDServiceProvider.removeRecord',
|
|
180
240
|
requestBody: {
|
|
181
241
|
entity: {
|
|
@@ -186,6 +246,83 @@ await sankhya.execService({
|
|
|
186
246
|
}
|
|
187
247
|
}
|
|
188
248
|
});
|
|
249
|
+
|
|
250
|
+
// Retorno Exemplo:
|
|
251
|
+
// {
|
|
252
|
+
// "serviceName": "CRUDServiceProvider.removeRecord",
|
|
253
|
+
// "status": "1",
|
|
254
|
+
// "pendingPrinting": "false",
|
|
255
|
+
// "transactionId": "123456789",
|
|
256
|
+
// "responseBody": {}
|
|
257
|
+
// }
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### 5. Execução de Serviço MgeCom (execServiceMgeCom)
|
|
263
|
+
|
|
264
|
+
Para serviços diversos do Sankhya que utilizam o endpoint **mgecom** (`/gateway/v1/mgecom/service.sbr`), como inclusão de notas, operações comerciais, etc. Este método recebe o `serviceName` e o `requestBody` em **formato JSON simples** e transforma automaticamente todos os valores primitivos (strings/números) para o formato `{ "$": "valor" }` exigido pelo Sankhya.
|
|
265
|
+
|
|
266
|
+
> **Nota:** Diferente do `execServiceMge` que usa `/gateway/v1/mge/service.sbr`, este método envia as requisições para `/gateway/v1/mgecom/service.sbr`.
|
|
267
|
+
|
|
268
|
+
#### Exemplo: Incluir Pedido de Venda / Nota (CACSP.incluirNota)
|
|
269
|
+
```typescript
|
|
270
|
+
const nota = await sankhya.execServiceMgeCom('CACSP.incluirNota', {
|
|
271
|
+
nota: {
|
|
272
|
+
cabecalho: {
|
|
273
|
+
CODPARC: "3",
|
|
274
|
+
DTNEG: "03/07/2023",
|
|
275
|
+
CODTIPOPER: "1718",
|
|
276
|
+
CODTIPVENDA: "34",
|
|
277
|
+
CODVEND: "0",
|
|
278
|
+
CODEMP: "15",
|
|
279
|
+
TIPMOV: "V", // V = Venda | C=Compra | D=Devolução | etc.
|
|
280
|
+
CODNAT: "10101002",
|
|
281
|
+
CODCENCUS: "10600200",
|
|
282
|
+
SERIE: "14"
|
|
283
|
+
},
|
|
284
|
+
itens: {
|
|
285
|
+
INFORMARPRECO: "True",
|
|
286
|
+
item: [
|
|
287
|
+
{
|
|
288
|
+
CODPROD: "6",
|
|
289
|
+
QTDNEG: "1",
|
|
290
|
+
CODLOCALORIG: "0",
|
|
291
|
+
CODVOL: "SV",
|
|
292
|
+
PERCDESC: "0",
|
|
293
|
+
VLRUNIT: "81.75"
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
A biblioteca transforma automaticamente o payload acima para o formato exigido pelo Sankhya antes do envio:
|
|
302
|
+
|
|
303
|
+
```json
|
|
304
|
+
{
|
|
305
|
+
"serviceName": "CACSP.incluirNota",
|
|
306
|
+
"requestBody": {
|
|
307
|
+
"nota": {
|
|
308
|
+
"cabecalho": {
|
|
309
|
+
"CODPARC": { "$": "3" },
|
|
310
|
+
"DTNEG": { "$": "03/07/2023" },
|
|
311
|
+
"CODTIPOPER": { "$": "1718" }
|
|
312
|
+
},
|
|
313
|
+
"itens": {
|
|
314
|
+
"INFORMARPRECO": { "$": "True" },
|
|
315
|
+
"item": [
|
|
316
|
+
{
|
|
317
|
+
"CODPROD": { "$": "6" },
|
|
318
|
+
"QTDNEG": { "$": "1" },
|
|
319
|
+
"CODVOL": { "$": "SV" }
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
189
326
|
```
|
|
190
327
|
|
|
191
328
|
## Funcionalidades
|
|
@@ -194,4 +331,5 @@ await sankhya.execService({
|
|
|
194
331
|
- *LoadRecords*: Retorna `Array<Objeto>`.
|
|
195
332
|
- *LoadRecord*: Retorna `Objeto` único (lida com ausência de metadados).
|
|
196
333
|
- **Transformação de Payload**: O método `saveRecord` aceita objetos simples JS (ex: `{ CAMPO: "Valor" }`) e os converte automaticamente para `{ CAMPO: { "$": "Valor" } }`.
|
|
334
|
+
- **Transformação Profunda de Payload**: O método `execServiceMgeCom` transforma recursivamente todos os valores primitivos de um objeto JSON aninhado para o formato `{ "$": "valor" }`, incluindo arrays e sub-objetos.
|
|
197
335
|
- **Tipagem TypeScript**: Suporte completo a interfaces para garantir segurança de tipo no desenvolvimento.
|
package/dist/Sankhya.d.ts
CHANGED
|
@@ -40,9 +40,51 @@ export declare class Sankhya {
|
|
|
40
40
|
put(path: string, body?: Record<string, any>, queryParam?: Record<string, any>, headers?: Record<string, any>): Promise<any>;
|
|
41
41
|
patch(path: string, body?: Record<string, any>, queryParam?: Record<string, any>, headers?: Record<string, any>): Promise<any>;
|
|
42
42
|
delete(path: string, queryParam?: Record<string, any>, headers?: Record<string, any>): Promise<any>;
|
|
43
|
-
|
|
43
|
+
execServiceMge(options: ExecServiceOptions, outputType?: 'json' | 'xml'): Promise<any>;
|
|
44
44
|
loadRecords({ rootEntity, includePresentationFields, offsetPage, criteria, entity }: LoadRecordsOptions, outputType?: 'json' | 'xml'): Promise<any>;
|
|
45
45
|
loadRecord({ rootEntity, includePresentationFields, criteria, entity, rows }: LoadRecordsOptions, outputType?: 'json' | 'xml'): Promise<any>;
|
|
46
46
|
saveRecord({ rootEntity, includePresentationFields, localFields, key, entity }: SaveRecordOptions, outputType?: 'json' | 'xml'): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Executa serviços diversos do Sankhya via endpoint mgecom.
|
|
49
|
+
* Recebe o serviceName e o requestBody em formato JSON simples,
|
|
50
|
+
* transformando automaticamente todos os valores primitivos para { "$": "valor" }.
|
|
51
|
+
*
|
|
52
|
+
* Endpoint: /gateway/v1/mgecom/service.sbr
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Exemplo: Inclusão de Pedido de Venda
|
|
57
|
+
* const nota = await sankhya.execServiceMgeCom('CACSP.incluirNota', {
|
|
58
|
+
* nota: {
|
|
59
|
+
* cabecalho: {
|
|
60
|
+
* CODPARC: "3",
|
|
61
|
+
* DTNEG: "03/07/2023",
|
|
62
|
+
* CODTIPOPER: "1718",
|
|
63
|
+
* CODTIPVENDA: "34",
|
|
64
|
+
* CODVEND: "0",
|
|
65
|
+
* CODEMP: "15",
|
|
66
|
+
* TIPMOV: "P",
|
|
67
|
+
* CODNAT: "10101002",
|
|
68
|
+
* CODCENCUS: "10600200",
|
|
69
|
+
* SERIE: "14"
|
|
70
|
+
* },
|
|
71
|
+
* itens: {
|
|
72
|
+
* INFORMARPRECO: "True",
|
|
73
|
+
* item: [
|
|
74
|
+
* {
|
|
75
|
+
* CODPROD: "6",
|
|
76
|
+
* QTDNEG: "1",
|
|
77
|
+
* CODLOCALORIG: "0",
|
|
78
|
+
* CODVOL: "SV",
|
|
79
|
+
* PERCDESC: "0",
|
|
80
|
+
* VLRUNIT: "81.75"
|
|
81
|
+
* }
|
|
82
|
+
* ]
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
execServiceMgeCom(serviceName: string, requestBody: Record<string, any>, outputType?: 'json' | 'xml'): Promise<any>;
|
|
47
89
|
private isEmptyObject;
|
|
48
90
|
}
|
package/dist/Sankhya.js
CHANGED
|
@@ -94,7 +94,7 @@ class Sankhya {
|
|
|
94
94
|
return response.data;
|
|
95
95
|
}
|
|
96
96
|
// Sankhya Specific Methods
|
|
97
|
-
async
|
|
97
|
+
async execServiceMge(options, outputType = 'json') {
|
|
98
98
|
// Standard Sankhya Service URL pattern: /mge/service.sbr?serviceName=...&outputType=json
|
|
99
99
|
const { serviceName, requestBody } = options;
|
|
100
100
|
// Construct the wrapper expected by Sankhya JSON API
|
|
@@ -110,7 +110,7 @@ class Sankhya {
|
|
|
110
110
|
}, {});
|
|
111
111
|
}
|
|
112
112
|
async loadRecords({ rootEntity, includePresentationFields = 'N', offsetPage = 0, criteria = {}, entity = {} }, outputType = 'json') {
|
|
113
|
-
return this.
|
|
113
|
+
return this.execServiceMge({
|
|
114
114
|
serviceName: 'CRUDServiceProvider.loadRecords',
|
|
115
115
|
requestBody: {
|
|
116
116
|
dataSet: {
|
|
@@ -125,7 +125,7 @@ class Sankhya {
|
|
|
125
125
|
}, outputType);
|
|
126
126
|
}
|
|
127
127
|
async loadRecord({ rootEntity, includePresentationFields = 'N', criteria = {}, entity = {}, rows = {} }, outputType = 'json') {
|
|
128
|
-
return this.
|
|
128
|
+
return this.execServiceMge({
|
|
129
129
|
serviceName: 'CRUDServiceProvider.loadRecord',
|
|
130
130
|
requestBody: {
|
|
131
131
|
dataSet: {
|
|
@@ -140,7 +140,7 @@ class Sankhya {
|
|
|
140
140
|
}, outputType);
|
|
141
141
|
}
|
|
142
142
|
async saveRecord({ rootEntity, includePresentationFields = 'N', localFields = {}, key = {}, entity = {} }, outputType = 'json') {
|
|
143
|
-
return this.
|
|
143
|
+
return this.execServiceMge({
|
|
144
144
|
serviceName: 'CRUDServiceProvider.saveRecord',
|
|
145
145
|
requestBody: {
|
|
146
146
|
dataSet: {
|
|
@@ -156,6 +156,59 @@ class Sankhya {
|
|
|
156
156
|
outputType
|
|
157
157
|
}, outputType);
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Executa serviços diversos do Sankhya via endpoint mgecom.
|
|
161
|
+
* Recebe o serviceName e o requestBody em formato JSON simples,
|
|
162
|
+
* transformando automaticamente todos os valores primitivos para { "$": "valor" }.
|
|
163
|
+
*
|
|
164
|
+
* Endpoint: /gateway/v1/mgecom/service.sbr
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* // Exemplo: Inclusão de Pedido de Venda
|
|
169
|
+
* const nota = await sankhya.execServiceMgeCom('CACSP.incluirNota', {
|
|
170
|
+
* nota: {
|
|
171
|
+
* cabecalho: {
|
|
172
|
+
* CODPARC: "3",
|
|
173
|
+
* DTNEG: "03/07/2023",
|
|
174
|
+
* CODTIPOPER: "1718",
|
|
175
|
+
* CODTIPVENDA: "34",
|
|
176
|
+
* CODVEND: "0",
|
|
177
|
+
* CODEMP: "15",
|
|
178
|
+
* TIPMOV: "P",
|
|
179
|
+
* CODNAT: "10101002",
|
|
180
|
+
* CODCENCUS: "10600200",
|
|
181
|
+
* SERIE: "14"
|
|
182
|
+
* },
|
|
183
|
+
* itens: {
|
|
184
|
+
* INFORMARPRECO: "True",
|
|
185
|
+
* item: [
|
|
186
|
+
* {
|
|
187
|
+
* CODPROD: "6",
|
|
188
|
+
* QTDNEG: "1",
|
|
189
|
+
* CODLOCALORIG: "0",
|
|
190
|
+
* CODVOL: "SV",
|
|
191
|
+
* PERCDESC: "0",
|
|
192
|
+
* VLRUNIT: "81.75"
|
|
193
|
+
* }
|
|
194
|
+
* ]
|
|
195
|
+
* }
|
|
196
|
+
* }
|
|
197
|
+
* });
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
async execServiceMgeCom(serviceName, requestBody, outputType = 'json') {
|
|
201
|
+
const transformedBody = SankhyaHelper_1.SankhyaHelper.transformDeepFields(requestBody);
|
|
202
|
+
const payload = {
|
|
203
|
+
serviceName,
|
|
204
|
+
requestBody: transformedBody
|
|
205
|
+
};
|
|
206
|
+
const response = await this.post('/gateway/v1/mgecom/service.sbr', payload, {
|
|
207
|
+
serviceName,
|
|
208
|
+
outputType
|
|
209
|
+
}, { 'Content-Type': 'application/json' });
|
|
210
|
+
return SankhyaHelper_1.SankhyaHelper.flattenMgeComResponse(response);
|
|
211
|
+
}
|
|
159
212
|
isEmptyObject(obj) {
|
|
160
213
|
return obj != null &&
|
|
161
214
|
obj.constructor === Object &&
|
package/dist/SankhyaHelper.d.ts
CHANGED
|
@@ -6,6 +6,22 @@ export declare class SankhyaHelper {
|
|
|
6
6
|
static processResponse(response: any, options?: {
|
|
7
7
|
serviceName?: string;
|
|
8
8
|
}): any;
|
|
9
|
+
/**
|
|
10
|
+
* Remove recursivamente os wrappers { "$": "valor" } do retorno do Sankhya,
|
|
11
|
+
* retornando um JSON limpo e amigável.
|
|
12
|
+
* Utilizado para tratar retornos do endpoint mgecom (ex: CACSP.incluirNota).
|
|
13
|
+
*/
|
|
14
|
+
static flattenMgeComResponse(obj: any): any;
|
|
15
|
+
/**
|
|
16
|
+
* Transforma recursivamente todos os valores primitivos (string/number) de um objeto
|
|
17
|
+
* para o formato Sankhya { "$": valor }, percorrendo objetos e arrays aninhados.
|
|
18
|
+
*
|
|
19
|
+
* Strings que são "irmãs" de arrays no mesmo objeto NÃO são encapsuladas,
|
|
20
|
+
* pois representam atributos XML (ex: INFORMARPRECO em "itens").
|
|
21
|
+
*
|
|
22
|
+
* Ex: { nota: { cabecalho: { CAMPO: "VALOR" } } } -> { nota: { cabecalho: { CAMPO: { "$": "VALOR" } } } }
|
|
23
|
+
*/
|
|
24
|
+
static transformDeepFields(obj: any): any;
|
|
9
25
|
/**
|
|
10
26
|
* Transforma um objeto simples de chave/valor para o formato do Sankhya
|
|
11
27
|
* Ex: { CAMPO: "VALOR" } -> { CAMPO: { "$": "VALOR" } }
|
package/dist/SankhyaHelper.js
CHANGED
|
@@ -22,6 +22,83 @@ class SankhyaHelper {
|
|
|
22
22
|
return response;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Remove recursivamente os wrappers { "$": "valor" } do retorno do Sankhya,
|
|
27
|
+
* retornando um JSON limpo e amigável.
|
|
28
|
+
* Utilizado para tratar retornos do endpoint mgecom (ex: CACSP.incluirNota).
|
|
29
|
+
*/
|
|
30
|
+
static flattenMgeComResponse(obj) {
|
|
31
|
+
if (obj === null || obj === undefined) {
|
|
32
|
+
return obj;
|
|
33
|
+
}
|
|
34
|
+
// Se for um objeto com apenas a chave "$", extrai o valor
|
|
35
|
+
if (typeof obj === 'object' && !Array.isArray(obj) && '$' in obj && Object.keys(obj).length === 1) {
|
|
36
|
+
return obj.$;
|
|
37
|
+
}
|
|
38
|
+
// Se for array, aplica recursivamente em cada elemento
|
|
39
|
+
if (Array.isArray(obj)) {
|
|
40
|
+
return obj.map(item => this.flattenMgeComResponse(item));
|
|
41
|
+
}
|
|
42
|
+
// Se for objeto, aplica recursivamente em cada propriedade
|
|
43
|
+
if (typeof obj === 'object') {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const key of Object.keys(obj)) {
|
|
46
|
+
result[key] = this.flattenMgeComResponse(obj[key]);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
return obj;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Transforma recursivamente todos os valores primitivos (string/number) de um objeto
|
|
54
|
+
* para o formato Sankhya { "$": valor }, percorrendo objetos e arrays aninhados.
|
|
55
|
+
*
|
|
56
|
+
* Strings que são "irmãs" de arrays no mesmo objeto NÃO são encapsuladas,
|
|
57
|
+
* pois representam atributos XML (ex: INFORMARPRECO em "itens").
|
|
58
|
+
*
|
|
59
|
+
* Ex: { nota: { cabecalho: { CAMPO: "VALOR" } } } -> { nota: { cabecalho: { CAMPO: { "$": "VALOR" } } } }
|
|
60
|
+
*/
|
|
61
|
+
static transformDeepFields(obj) {
|
|
62
|
+
// Campos com valor null ou undefined são tratados como placeholders (ex: PKs)
|
|
63
|
+
// e enviados como objeto vazio {} no formato Sankhya
|
|
64
|
+
if (obj === null || obj === undefined) {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
// Se for string ou number, transforma para { "$": valor }
|
|
68
|
+
// (este caso é chamado recursivamente; a decisão de NÃO transformar
|
|
69
|
+
// é feita no nível do objeto pai, abaixo)
|
|
70
|
+
if (typeof obj === 'string' || typeof obj === 'number') {
|
|
71
|
+
return { $: String(obj) };
|
|
72
|
+
}
|
|
73
|
+
// Se for array, aplica recursivamente em cada elemento
|
|
74
|
+
if (Array.isArray(obj)) {
|
|
75
|
+
return obj.map(item => this.transformDeepFields(item));
|
|
76
|
+
}
|
|
77
|
+
// Se já estiver no formato { "$": ... }, mantém como está
|
|
78
|
+
if (typeof obj === 'object' && '$' in obj && Object.keys(obj).length === 1) {
|
|
79
|
+
return obj;
|
|
80
|
+
}
|
|
81
|
+
// Se for objeto, aplica recursivamente em cada propriedade
|
|
82
|
+
if (typeof obj === 'object') {
|
|
83
|
+
const keys = Object.keys(obj);
|
|
84
|
+
// Verifica se o objeto possui algum filho que é array.
|
|
85
|
+
// Se sim, strings neste nível são atributos XML e NÃO devem ser encapsuladas.
|
|
86
|
+
const hasArrayChild = keys.some(k => Array.isArray(obj[k]));
|
|
87
|
+
const transformed = {};
|
|
88
|
+
for (const key of keys) {
|
|
89
|
+
const value = obj[key];
|
|
90
|
+
if (hasArrayChild && (typeof value === 'string' || typeof value === 'number')) {
|
|
91
|
+
// Atributo XML: mantém como string pura
|
|
92
|
+
transformed[key] = value;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
transformed[key] = this.transformDeepFields(value);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return transformed;
|
|
99
|
+
}
|
|
100
|
+
return obj;
|
|
101
|
+
}
|
|
25
102
|
/**
|
|
26
103
|
* Transforma um objeto simples de chave/valor para o formato do Sankhya
|
|
27
104
|
* Ex: { CAMPO: "VALOR" } -> { CAMPO: { "$": "VALOR" } }
|