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

Deixe um comentário