Olá pessoal.
Nos post anterior vimos:
- Parte 1 – Como configurar, testar API no Protheus e listar fornecedores no Angular (PO.UI) aqui.
- Parte 2 – Como criar o formulário para inclusão de fornecedor aqui.
Dando continuidade na nossa série de criar um CRUD em PO.UI, vamos agora criar as ações de editar e excluir um fornecedor.
Vamos começar com a exclusão, para isso vamos usar a mesma API mas o verbo agora será DELETE ao invés de GET ou POST. Vamos primeiro testar nossa API e consultar se nosso backend está funcionando corretamente (essa etapa é opcional), para isso vamos usar novamente o Postman, apontando para nossa API passaremos o código + loja do fornecedor como parâmetro na URL, ficando assim, http://localhost:8084/rest/api/crm/v1/customerVendor/2/A2_COD+A2_LOJA(no lugar de A2_COD+A2_LOJA informe um fornecedor e loja que exista em seu ambiente, e também troque o ip e porta do backend para os seus dados) como no print abaixo.

A resposta deverá ser um arquivo JSON com a mensagem de registro deletado com sucesso, se tudo ocorreu corretamente aqui, vamos começar a tratar nosso frontend para usar a mesma API.
A Primeira etapa do FrontEnd será ajustar o componente de lista fornecedores para adicionar duas novas ações para cada item na lista(editar e excluir), para isso altere o arquivo supplier-list.component.ts e deixe como o código abaixo:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { PoNotificationService, PoTableAction } from '@po-ui/ng-components';
import { SupplierListService } from './supplier-list.service';
@Component({
selector: 'app-supplier-list',
templateUrl: './supplier-list.component.html',
styleUrls: ['./supplier-list.component.css']
})
export class SupplierListComponent implements OnInit {
supplierList: Array<any> = new Array();
colunasTable: Array<any> = new Array();
//Parte 3
//Adicionado ação deleter e editar
actions: Array<PoTableAction> = [
{ action: this.updateSupplier.bind(this), icon: 'po-icon-edit', label: 'Alterar Fornecedor'},
{ action: this.deleteSupplier.bind(this), icon: 'po-icon-delete', label: 'Excluir Fornecedor' }
];
//Parte 3
//método para editar
updateSupplier(row: any) {
console.log('Edit');
const supplierId = row.code + row.storeId;
this.router.navigate([`/supplierform/${supplierId}/${row.type}`]);
}
//Parte 3
//método para deleter o fornecedor
deleteSupplier(row: any) {
console.log('deleteSupplier');
const supplierId = row.code + row.storeId;
this.SupplierListService
.deleteSupplier(supplierId, row.type)
.subscribe(() => {
this.updateSupplierList(); //atualiza a lista
this.poNotification.success('o Fornecedor foi excluido com sucesso');
}
, err => this.poNotification.error(err)); //exibe erro
}
constructor(private SupplierListService: SupplierListService,
private router: Router,
private poNotification: PoNotificationService) { }
ngOnInit(): void {
this.updateSupplierList(); //busca a lista de fornecedores do nosso Api
this.colunasTable = this.SupplierListService.getColumns(); //atualiza as colunas que queremos ser listadas em nossa tabela.
}
//Metódo responsável por se isncrever no serviço e atualizar a lista de fornecedores
updateSupplierList(): void {
this.SupplierListService.getSupplierList().subscribe(response => {
this.supplierList = response.items;
});
}
}
Foram incluídos:
- Nova variável chamada actions com as ações que desejamos em nossa lista.
- Novos métodos
- updateSupplier, será responsável por atualizar um fornecedor (opção de editar).
-
deleteSupplier, será responsável por deletar um fornecedor.
Agora devemos ajustar o arquivo supplier-list.service.ts e incluir o método responsável por enviar para nossa API a requisição de exclusão, o arquivo final deve ficar como o código abaixo:
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { PoTableColumn } from '@po-ui/ng-components';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SupplierListService {
ApiRest = 'http://localhost:8084/rest/api/crm/v1/customerVendor'; //Endereço da nossa API responsável por lista os fornecedores
constructor(private http: HttpClient) { }
//Método responsável por buscar e listar nossos fornecedores
getSupplierList(): Observable<any> {
return this.http.get(this.ApiRest + `/2`); //supplier
}
//Método para remover Fornecedor
deleteSupplier(Id: string, type: string = '2') {
return this.http.delete(this.ApiRest + `/${type}/${Id}`);
}
//Método responsável por converter em nomes mais legiveis para usuário
getColumns(): Array<PoTableColumn> {
return [
{ property: 'code', label: 'Código'},
{ property: 'storeId', label: 'Loja' },
{ property: 'name', label: 'Nome' },
{ property: 'strategicCustomerType', label: 'Fisica/Juridica' ,
type: 'label', //part3 add
labels: [
{ value: 'F',color: 'color-08', label: 'Física' },
{ value: 'J', color: 'color-12',label: 'Juridica' }
] },
{ property: 'registerSituation', label: 'Situação' ,
type: 'label', //part3 add
labels: [
{ value: '1', color: 'color-07', label: 'Inativo' },
{ value: '2', color: 'color-11', label: 'Ativo' },
{ value: '3', color: 'color-09', label: 'Cancelado' },
{ value: '4', color: 'color-12', label: 'Pendente' },
{ value: '5', color: 'color-08', label: 'Suspenso' }
] },
];
}
}
E para finalizar a opção de excluir, vamos alterar o arquivo supplier-list.component.html e no component po-table adicionar as nossas ações, o arquivo final deve ficar como o código abaixo:
<po-page-default p-title="Lista de Fornecedores">
<po-table
p-container="light"
[p-columns]="colunasTable"
[p-items]="supplierList"
[p-actions]="actions"><!-- adicionado part 3 -->
</po-table>
</po-page-default>
Para finalizarmos nossa série e fazer a edição de um registro, vamos precisar primeiramente incluir uma nova rota (vamos reutilizar o mesmo form de inclusão mas agora vamos receber na URL o código + loja do fornecedor, para isso no arquivo app-routing.module.ts, vamos criar uma nova rota que receberá 2 parâmetros, um o ID do nosso fornecedor e outro para o tipo (nosso caso será sempre 2 = fornecedor, mas poderíamos editar facilmente um cliente por exemplo), o arquivo final deve ficar como o código abaixo:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SupplierListComponent } from './supplier-list/supplier-list.component';
import { SupplierFormComponent } from './supplier-form/supplier-form.component';
const routes: Routes = [
{ path: '', component: SupplierListComponent },
{ path: 'supplier', component: SupplierListComponent }, //lista de fornecedor
{ path: 'supplierform', component: SupplierFormComponent }, //form do fornecedor - Incluir
{ path: 'supplierform/:id/:type', component: SupplierFormComponent }, //form do fornecedor - Editar
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Alteraremos também o arquivo supplier-form.component.ts, nele vamos precisar:
No ngOninit, vamos verificar se em nossa URL temos os parametros ID e Tipo (criados na nossa rota) se encontrar significa que estamos editando um fornecedor e nesse caso vamos carregar os dados do fornecedor e mudar o titulo da página.
Vamos criar a ação no novo botão “atualizar” para confirmar alterações em um forncedor (esse botão será criado no HTML do form, logo abaixo).
O arquivo supplier-form.component.ts deve ficar como o código abaixo:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { PoDynamicFormField, PoNotificationService } from '@po-ui/ng-components';
import { Supplier } from '../model/supplierModel';
import { SupplierFormService } from './supplier-form.service';
import { first } from 'rxjs/operators';
@Component({
selector: 'app-supplier-form',
templateUrl: './supplier-form.component.html',
styleUrls: ['./supplier-form.component.css']
})
export class SupplierFormComponent implements OnInit {
//fields: Array<PoDynamicFormField> = []; //campos "dinamicos" para usar no formulário
supplier: Supplier = new Supplier();//model de um fornecedor
supplierValues = { type: 2, code: "", storeId: "", shortName: "", name: "", strategicCustomerType: "J", entityType: "J",
number: "", address: "", zipCode: "", stateId: "", stateInternalId: "", registerSituation: "1",
stateDescription: "", complement: "", district: "", cityCode: "", cityDescription: ""}; //array com os valores do fomulário
supplierType: string | any = '2'; //no nosso exemplo será sempre 2=fornecedor, mas poderia ser 1=cliente
supplierId: string | any;
title = 'Inclusão de Fornecedor';
constructor(private supplierFormService: SupplierFormService, //servico do form
private poNotification: PoNotificationService, //usar as notificações do PO.UI
private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit(): void {
//define valores padrão para formulário
this.supplierValues = {
type: 2, code: "", storeId: "", shortName: "", name: "", strategicCustomerType: "J", entityType: "J",
number: "", address: "", zipCode: "", stateId: "", stateInternalId: "",registerSituation: "1",
stateDescription: "", complement: "", district: "", cityCode: "", cityDescription: ""
}
this.route.paramMap.subscribe(parameters => {
this.supplierId = parameters.get('id');
this.supplierType = parameters.get('type');
});
if (this.supplierId) { //se tem o ID na URL, significa alteração
this.title = 'Alteração de Fornecedor';
this.setFormValue(); //atribui os valores do API para o formulário
}
}
//Método para inserir um novo fornecedor
insertSupplier(): void {
this.getSupplierFromForm();
this.supplierFormService.postNewSupplier(JSON.stringify(this.supplier)) //grava o novo fornecedor
.pipe(first())
.subscribe(() => {
this.poNotification.success('Fornecedor foi inserido com Sucesso');
this.router.navigate(['/supplier']); //redireciona para lista de fornecedor
}, err => {
//se error devolve o erro do Backend para o usuário
let messErr = JSON.parse(err.error.errorMessage);
this.poNotification.error(`Erro código ${messErr.code}, ${decodeURIComponent(escape(messErr.message))}, detalhe: ${decodeURIComponent(escape(messErr.detailedMessage))}.`)
}
); //exibe erro ao inserir fornecedor
}
//alimenta o modelo de dados
private getSupplierFromForm(): void {
// dados pessoais
this.supplier.code = this.supplierValues.code;
this.supplier.storeId = this.supplierValues.storeId;
this.supplier.name = this.supplierValues.name;
this.supplier.shortName = this.supplierValues.shortName;
this.supplier.strategicCustomerType = this.supplierValues.strategicCustomerType;
this.supplier.entityType = this.supplierValues.entityType;
this.supplier.type = this.supplierValues.type;
this.supplier.registerSituation = this.supplierValues.registerSituation;
// Endereço
this.supplier.address.address = this.supplierValues.address;
this.supplier.address.city.cityCode = this.supplierValues.cityCode;
this.supplier.address.city.cityDescription = this.supplierValues.cityCode;
this.supplier.address.city.cityInternalId = this.supplierValues.cityCode;
this.supplier.address.state.stateId = this.supplierValues.stateId;
this.supplier.address.state.stateInternalId = this.supplierValues.stateId;
}
//part 3
//Método para editar um fornecedor
updateSupplier(): void {
this.getSupplierFromForm(); //seta no modelo fornecedor os valores do Formulário para então enviar para API
this.supplierFormService
.putSupplier(this.supplier.code + this.supplier.storeId, JSON.stringify(this.supplier), this.supplierType)
.pipe(first())
.subscribe(() => {
this.poNotification.success('Fornecedor alterado com Sucesso');
this.router.navigate(['/supplier']);//redireciona para lista de fornecedor
}, err => this.poNotification.error(err));//exibe erro ao editar fornecedor
}
//part 3
//Método para atribuir valores aos campos para formulário
private setFormValue(): void {
this.supplierFormService
.getSupplier(this.supplierId, this.supplierType)
.pipe(first())
.subscribe((supplier:Supplier) => {
console.log(supplier);
this.supplierValues.code = supplier.code;
this.supplierValues.storeId = supplier.storeId;
this.supplierValues.name = supplier.name;
this.supplierValues.shortName = supplier.shortName;
this.supplierValues.strategicCustomerType = supplier.strategicCustomerType;
this.supplierValues.entityType = supplier.strategicCustomerType;
this.supplierValues.type = supplier.type;
this.supplierValues.registerSituation = supplier.registerSituation;
// Endereço
this.supplierValues.address = supplier.address.address;
this.supplierValues.cityCode = supplier.address.city.cityCode;
this.supplierValues.cityCode = supplier.address.city.cityDescription;
this.supplierValues.cityCode = supplier.address.city.cityInternalId;
this.supplierValues.stateId = supplier.address.state.stateId;
this.supplierValues.stateId = supplier.address.state.stateInternalId;
});
}
//array para definir os nomes dos campos do formulário
fields: Array<PoDynamicFormField> = [
{
property: 'code',
label: 'Código',
divider: 'Dados Pessoais',
maxLength: 6
},
{
property: 'storeId',
label: 'Loja',
maxLength: 2
},
{
property: 'name',
label: 'Nome',
maxLength: 40
},
{
property: 'shortName',
label: 'Nome Reduzido',
maxLength: 20
},
{
property: 'strategicCustomerType',
label: 'Tipo do cliente',
options: [
{ label: 'Cons. Final', value: 'F' },
{ label: 'Produtor Rural', value: 'L' },
{ label: 'Revendedor', value: 'R' },
{ label: 'Solidario', value: 'S' },
{ label: 'Exportação', value: 'X' }
]
},
{
property: 'entityType',
label: 'Tipo da entidade',
options: [
{ label: 'Juridica', value: 'J' },
{ label: 'Fisica', value: 'F' }
]
},
{
property: 'registerSituation', //Campo: A1_MSBLQL / A2_MSBLQL == Status: 1 - Ativo, 2 - Inativo, 3 - Cancelado, 4 - Pendente, 5 -Suspenso
label: 'Situação(MSBLQL)',
options: [
{ label: 'Inativo', value: '1' },
{ label: 'Ativo', value: '2' }
]
},
{
property: 'type',
label: 'Tipo',
options: [
{ label: 'Cliente', value: 1 },
{ label: 'Fornecedor', value: 2 }
]
},
{
property: 'zipCode',
label: 'CEP',
divider: 'Endereço',
maxLength: 9
},
{
property: 'address',
label: 'Endereço'
},
{
property: 'cityCode',
label: 'Cidade',
options: [
{ label: 'Adolfo', value: '00204' },
{ label: 'São José do Rio Preto', value: '49805' },
{ label: 'José Bonifácio', value: '25706' },
{ label: 'Joinville', value: '09102' }
]
},
{
property: 'stateId',
label: 'Estado',
options: [
{ label: 'Santa Catarina', value: 'SC' },
{ label: 'São Paulo', value: 'SP' },
{ label: 'Rio de Janeiro', value: 'RJ' },
{ label: 'Minas Gerais', value: 'MG' }
]
},
/*{
property: 'branchId',
label: 'Filial',
divider: 'Sistemico'
},
{
property: 'companyInternalId',
label: 'Empresa'
}*/
]
}
Agora a ultima etapa é ajustar o html que irá exibir os dados do nosso formulário para o usuário, para isso, edite o arquivo supplier-form.component.html, nele temos dois botões que serão exibidos em momentos diferentes, um para inclusão (action insertSupplier) e outro para alteração(updateSupplier), o que controlará quando cada um deve aparecer é a variavel no *ngIf, e deixe com a seguinte informação:
<po-page-default [p-title]="title"> <po-dynamic-form #dynamicForm [p-fields]="fields" [p-value]="supplierValues"> </po-dynamic-form> <div class="thf-row"> <po-button class="thf-md-3" *ngIf="!this.supplierId" p-label="Inserir" (p-click)="insertSupplier()"> </po-button> </div> <po-button *ngIf="this.supplierId" class="thf-md-3" p-label="Atualizar Fornecedor" (p-click)="updateSupplier()"> </po-button> </po-page-default>
Após todas essas etapas, ao acessar o endereço http://localhost:4200/supplier, deve ser exibida a lista de fornecedores, se clicarmos nas ações e em excluir, o mesmo deve ser removido e a lista carregada, se selecionarmos a opção editar, o formulário deve ser aberto com os dados preenchidos, o resultado final da lista será semelhante ao print abaixo:

O código fonte desse e de outros exemplos podem ser encontrados em nosso git oficial.
Post interessantes:
Aprenda a instalar o Protheus no Windows aqui.
Aprenda a instalar o Protheus no Linux aqui.
configurar serviço rest aqui.
Retornar datas por extenso aqui.
Barras de progresso aqui.
Dúvidas e sugestões, entre em contato.
Obrigado e até a próxima!
0 comentário