Commit ed044d10 authored by Rafael's avatar Rafael

Adiciona telas dos dados de proposta.

parent 75729ccf
......@@ -90,7 +90,7 @@
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "4.0.0-alpha.58",
"@material-ui/pickers": "^3.3.10",
"@microcredito/client": "^0.7.13",
"@microcredito/client": "^0.7.14",
"@reduxjs/toolkit": "^1.2.5",
"@types/react-swipeable-views": "^0.13.1",
"@types/react-swipeable-views-utils": "^0.13.3",
......
This diff is collapsed.
import { BDProductService } from '@agiliza/api/domain'
export const productServices = Array.from(Array(10).keys()).map<BDProductService>((p) => ({
id: `${p + 1}`,
description: `Descrição ${p + 1}`,
unit: `Unidade ${p + 1}`,
monthlySales: { price: Math.ceil(Math.random() * 1000).toString(), amount: Math.ceil(Math.random() % 11).toString() },
......
import { Entity } from '../../shared'
import { Entity } from '@agiliza/utils/method'
export interface BDProductService extends Entity {
description: string
......@@ -26,3 +26,33 @@ export interface DeleteBDProductServiceArgs {
projectId: string
productServiceId: string
}
interface InputGetBDProductsServices {
projectId: string
}
export interface GetBDProductsServices {
Input: InputGetBDProductsServices
Output: BDProductService[]
}
interface InputAddBDProductService {
projectId: string
productService: BDProductService
}
export interface AddBDProductService {
Input: InputAddBDProductService
Output: BDProductService[]
}
interface InputUpdateBDProductService {
projectId: string
productServiceId: string
productService: BDProductService
}
export interface UpdateBDProductService {
Input: InputUpdateBDProductService
Output: BDProductService[]
}
......@@ -16,11 +16,26 @@ export interface MaritalStatus extends Entity {
description: string
}
export interface ReferenceType extends Entity {
description: string
}
export interface DeedRecord extends Entity {
description: string
}
export interface HomeType extends Entity {
description: string
}
export interface ProposalDataContext {
frameworks: Framework[]
genders: Gender[]
schoolings: Schooling[]
maritalStatus: MaritalStatus[]
referenceTypes: ReferenceType[]
homeTypes: HomeType[]
deedRecords: DeedRecord[]
}
export interface FetchContext {
......
import { IPAddress } from './address'
import { Address } from '../'
export interface Home {
type: string
......@@ -8,6 +8,18 @@ export interface Home {
resideTime: string
cityResideTime: string
marketValue: string
address: IPAddress
address: Address
deed: string
proof: string
}
interface InputUpdateCDHome {
projectId: string
personId: string
home: Home
}
export interface UpdateCDHome {
Input: InputUpdateCDHome
Output: Home
}
......@@ -6,7 +6,7 @@ export interface InvolvedPerson {
personalData?: PersonalData
sourceIncome?: SourceIncome
address?: InvolvedPersonAddress
// home?: Home
home?: Home
// spousePersonalData?: SpousePersonalData
// vehicles?: Vehicle[]
// references?: Reference[]
......
......@@ -8,3 +8,36 @@ export interface Reference extends Entity {
extraInfo: string
concept: string
}
interface InputGetReferences {
projectId: string
personId: string
}
export interface GetCDReferences {
Input: InputGetReferences
Output: Reference[]
}
interface InputAddCDReference {
projectId: string
personId: string
reference: Reference
}
export interface AddCDReference {
Input: InputAddCDReference
Output: Reference[]
}
interface InputUpdateCDReference {
projectId: string
personId: string
referenceId: string
reference: Reference
}
export interface UpdateCDReference {
Input: InputUpdateCDReference
Output: Reference[]
}
......@@ -28,3 +28,36 @@ export interface DeleteVehicleArgs {
personId: string
vehicleId: string
}
interface InputGetCDVehicles {
projectId: string
personId: string
}
export interface GetCDVehicles {
Input: InputGetCDVehicles
Output: Vehicle[]
}
interface InputAddCDVehicles {
projectId: string
personId: string
vehicle: Vehicle
}
export interface AddCDVehicle {
Input: InputAddCDVehicles
Output: Vehicle[]
}
interface InputUpdateCDVehicles {
projectId: string
personId: string
vehicleId: string
vehicle: Vehicle
}
export interface UpdateCDVehicle {
Input: InputUpdateCDVehicles
Output: Vehicle[]
}
import { BusinessData, CreateProposal, Document, UpdateBDIdentification } from '@agiliza/api/domain'
import {
AddBDProductService,
BDProductService,
BusinessData,
CreateProposal,
Document,
UpdateBDIdentification,
UpdateBDProductService
} from '@agiliza/api/domain'
import { extractNumbers } from '@agiliza/utils/extractors'
import { DadosNegocioIdentificacaoApiModel, DocumentoApiModel } from '@microcredito/client'
import { AtualizarIdentificacaoDadosNegocioRequest } from '@microcredito/client/dist/apis/AgenteApi'
import {
DadosNegocioIdentificacaoApiModel,
DadosNegocioProdutoServicoApiModel,
DocumentoApiModel
} from '@microcredito/client'
import {
AtualizaProdutoServicoDadosNegocioRequest,
AtualizarIdentificacaoDadosNegocioRequest,
CriarProdutoServicoDadosNegocioRequest
} from '@microcredito/client/dist/apis/AgenteApi'
import { CriarPropostaRequest } from '@microcredito/client/dist/apis/ClienteApi'
import { ApiAdapter } from '../shared'
......@@ -63,3 +79,41 @@ export class CreateProposalApiMapper implements ApiAdapter<CreateProposal['Input
},
})
}
export class BDProductServiceApiMapper implements ApiAdapter<BDProductService, DadosNegocioProdutoServicoApiModel> {
public mapPriceAmountToDomain = (pA: { price: string; amount: string }): DadosNegocioProdutoServicoApiModel['custosVariaveis'] => ({
precoUnitario: Number(pA.price),
quantidade: Number(pA.amount),
})
public mapDomainToApiModel = (pS: BDProductService): DadosNegocioProdutoServicoApiModel => ({
id: pS.id,
unidade: pS.unit,
descricao: pS.description,
custosVariaveis: this.mapPriceAmountToDomain(pS.variableCosts),
estoque: this.mapPriceAmountToDomain(pS.stock),
vendasMensais: this.mapPriceAmountToDomain(pS.monthlySales),
})
}
export class BDAddProductServiceApiMapper implements ApiAdapter<AddBDProductService['Input'], CriarProdutoServicoDadosNegocioRequest> {
private bdProductServiceApiMapper: BDProductServiceApiMapper
constructor() {
this.bdProductServiceApiMapper = new BDProductServiceApiMapper()
}
public mapDomainToApiModel = (input: AddBDProductService['Input']): CriarProdutoServicoDadosNegocioRequest => ({
projetoId: input.projectId,
dadosNegocioProdutoServicoApiModel: this.bdProductServiceApiMapper.mapDomainToApiModel(input.productService),
})
}
export class BDUpdateProductServiceApiMapper implements ApiAdapter<UpdateBDProductService['Input'], AtualizaProdutoServicoDadosNegocioRequest> {
private bdProductServiceApiMapper: BDProductServiceApiMapper
constructor() {
this.bdProductServiceApiMapper = new BDProductServiceApiMapper()
}
public mapDomainToApiModel = (input: UpdateBDProductService['Input']): AtualizaProdutoServicoDadosNegocioRequest => ({
projetoId: input.projectId,
prdSrvId: input.productServiceId,
dadosNegocioProdutoServicoApiModel: this.bdProductServiceApiMapper.mapDomainToApiModel(input.productService),
})
}
import {
AddCDIdentification,
AddCDReference,
AddCDVehicle,
Address,
Home,
InvolvedPerson,
Reference,
RG,
SourceIncome,
SpousePersonalData,
UpdateCDAddress,
UpdateCDHome,
UpdateCDPersonalData,
UpdateCDReference,
UpdateCDSourceIncome,
UpdateCDSpouseData
UpdateCDSpouseData,
UpdateCDVehicle,
Vehicle
} from '@agiliza/api/domain'
import { extractNumbers } from '@agiliza/utils/method'
import {
EnderecoApiModel,
ProjetoPessoaEnvolvidaConjugeApiModel,
ProjetoPessoaEnvolvidaDadosMoradiaApiModel,
ProjetoPessoaEnvolvidaDadosPessoaisApiModel,
ProjetoPessoaEnvolvidaFonteRendaApiModel,
ProjetoPessoaEnvolvidaIdentificacaoApiModel,
ProjetoPessoaEnvolvidaRGApiModel
ProjetoPessoaEnvolvidaReferenciaApiModel,
ProjetoPessoaEnvolvidaRGApiModel,
ProjetoPessoaEnvolvidaVeiculoApiModel
} from '@microcredito/client'
import {
AtualiarReferenciaPessoaEnvolvidaRequest,
AtualizarConjugePessoaEnvolvidaRequest,
AtualizarDadosMoradiaPessoaEnvolvidaRequest,
AtualizarDadosPessoaisPessoaEnvolvidaRequest,
AtualizarEnderecoPessoaEnvolvidaRequest,
AtualizarFonteRendaPessoaEnvolvidaRequest,
AtualizarVeiculoPessoaEnvolvidaRequest,
CriarReferenciaPessoaEnvolvidaRequest,
CriarVeiculoPessoaEnvolvidaRequest,
IncluirPessoaEnvolvidaRequest
} from '@microcredito/client/dist/apis/AgenteApi'
......@@ -34,7 +50,7 @@ export class AddInvolvedPersonIdentification implements ApiAdapter<InvolvedPerso
acc: InvolvedPerson['identification']['account']
): ProjetoPessoaEnvolvidaIdentificacaoApiModel['contaBanestes'] => ({
numeroConta: acc?.number,
fotoCartao: acc?.cardPicture?.split(',')[1],
fotoCartao: acc?.cardPicture,
numeroAgencia: acc?.agencyNumber,
})
......@@ -70,8 +86,8 @@ export class CDAddIdentificationMapper implements ApiAdapter<AddCDIdentification
export class RGApiAdapter implements ApiAdapter<RG, ProjetoPessoaEnvolvidaRGApiModel> {
public mapDomainToApiModel = (rg: RG): ProjetoPessoaEnvolvidaRGApiModel => ({
frente: rg.front.split(',')[1] || '',
verso: rg.back.split(',')[1] || '',
frente: rg.front || '',
verso: rg.back || '',
orgaoExpedidor: rg.dispatcherAgency,
numero: rg.number,
})
......@@ -123,7 +139,7 @@ export class CDUpdateAddressApiMapper implements ApiAdapter<UpdateCDAddress['Inp
projetoId: input.projectId,
pessoaId: input.personId,
projetoPessoaEnvolvidaEnderecoApiModel: {
comprovante: input.address.proof.split(',')[1],
comprovante: input.address.proof,
endereco: this.addressApiMapper.mapDomainToApiModel(input.address),
},
})
......@@ -151,7 +167,7 @@ export class CDUpdateSourceIncomeApiMapper implements ApiAdapter<UpdateCDSourceI
private mapSourceIncomeToApi = (sI: SourceIncome): ProjetoPessoaEnvolvidaFonteRendaApiModel => ({
cnpj: extractNumbers(sI.cnpj),
cargoFuncao: sI.position,
fotoComprovante: sI.proofAddress.split(',')[1],
fotoComprovante: sI.proofAddress,
telefone: extractNumbers(sI.mobile),
razaoSocial: sI.companyName,
dataAdmissao: sI.admissionDate || undefined,
......@@ -184,7 +200,7 @@ export class CDUpdateSpouseDataApiMapper implements ApiAdapter<UpdateCDSpouseDat
profissao: spouse.occupation,
rg: spouse.rg ? this.rgApiAdapter.mapDomainToApiModel(spouse.rg) : undefined,
usuarioCRAS: spouse.userCRAS,
certidaoCasamento: spouse.marriageCertificate,
certidaoCasamento: spouse.marriageCertificate || '',
})
public mapDomainToApiModel = (input: UpdateCDSpouseData['Input']): AtualizarConjugePessoaEnvolvidaRequest => ({
projetoId: input.projectId,
......@@ -192,3 +208,110 @@ export class CDUpdateSpouseDataApiMapper implements ApiAdapter<UpdateCDSpouseDat
projetoPessoaEnvolvidaConjugeApiModel: this.mapSpouseDataToApi(input.spouseData),
})
}
export class ReferenceApiMapper implements ApiAdapter<Reference, ProjetoPessoaEnvolvidaReferenciaApiModel> {
public mapDomainToApiModel = (ref: Reference): ProjetoPessoaEnvolvidaReferenciaApiModel => ({
id: ref.id || undefined,
conceito: ref.concept,
foto: ref.photo || '',
nome: ref.name,
outrasInformacoes: ref.extraInfo,
telefone: extractNumbers(ref.telephone),
tipo: ref.type ? Number(ref.type) : undefined,
})
}
export class CDAddReferenceApiMapper implements ApiAdapter<AddCDReference['Input'], CriarReferenciaPessoaEnvolvidaRequest> {
private referenceApiMapper: ReferenceApiMapper
constructor() {
this.referenceApiMapper = new ReferenceApiMapper()
}
public mapDomainToApiModel = (input: AddCDReference['Input']): CriarReferenciaPessoaEnvolvidaRequest => ({
projetoId: input.projectId,
pessoaId: input.personId,
projetoPessoaEnvolvidaReferenciaApiModel: this.referenceApiMapper.mapDomainToApiModel(input.reference),
})
}
export class CDUpdateReferenceApiMapper implements ApiAdapter<UpdateCDReference['Input'], AtualiarReferenciaPessoaEnvolvidaRequest> {
private referenceApiMapper: ReferenceApiMapper
constructor() {
this.referenceApiMapper = new ReferenceApiMapper()
}
public mapDomainToApiModel = (input: UpdateCDReference['Input']): AtualiarReferenciaPessoaEnvolvidaRequest => ({
projetoId: input.projectId,
pessoaId: input.personId,
referenciaId: input.referenceId,
projetoPessoaEnvolvidaReferenciaApiModel: this.referenceApiMapper.mapDomainToApiModel(input.reference),
})
}
export class HomeApiMapper implements ApiAdapter<Home, ProjetoPessoaEnvolvidaDadosMoradiaApiModel> {
private addressApiAdapter: AddressApiMapper
constructor() {
this.addressApiAdapter = new AddressApiMapper()
}
public mapDomainToApiModel = (home: Home): ProjetoPessoaEnvolvidaDadosMoradiaApiModel => ({
endereco: home.address ? this.addressApiAdapter.mapDomainToApiModel(home.address) : undefined,
escritura: home.deed,
possuiOnus: home.hasOnus,
registroEscritura: Number(home.deedRecord),
resideImovel: home.reside,
tempoLocal: Number(home.resideTime),
tempoMunicipio: Number(home.cityResideTime),
tipo: Number(home.type),
valorMercado: home.marketValue ? Number(extractNumbers(home.marketValue)) : undefined,
})
}
export class CDUpdateHomeApiMapper implements ApiAdapter<UpdateCDHome['Input'], AtualizarDadosMoradiaPessoaEnvolvidaRequest> {
private homeApiMapper: HomeApiMapper
constructor() {
this.homeApiMapper = new HomeApiMapper()
}
public mapDomainToApiModel = (input: UpdateCDHome['Input']): AtualizarDadosMoradiaPessoaEnvolvidaRequest => ({
projetoId: input.projectId,
pessoaId: input.personId,
projetoPessoaEnvolvidaDadosMoradiaApiModel: this.homeApiMapper.mapDomainToApiModel(input.home),
})
}
export class VehicleApiMapper implements ApiAdapter<Vehicle, ProjetoPessoaEnvolvidaVeiculoApiModel> {
public mapDomainToApiModel = (vhcl: Vehicle): ProjetoPessoaEnvolvidaVeiculoApiModel => ({
id: vhcl.id,
ano: vhcl.year ? Number(vhcl.year) : undefined,
documento: vhcl.document,
marca: vhcl.brand,
modelo: vhcl.model,
placa: vhcl.licensePlate.replace(/(\W)/g, ''),
possuiOnus: vhcl.hasOnus,
possuiSeguro: vhcl.hasInsurance,
valorMercado: vhcl.marketValue ? Number(vhcl.marketValue) / 100 : undefined,
})
}
export class CDAddVehicleApiMapper implements ApiAdapter<AddCDVehicle['Input'], CriarVeiculoPessoaEnvolvidaRequest> {
private vehicleApiMapper: VehicleApiMapper
constructor() {
this.vehicleApiMapper = new VehicleApiMapper()
}
public mapDomainToApiModel = (input: AddCDVehicle['Input']): CriarVeiculoPessoaEnvolvidaRequest => ({
projetoId: input.projectId,
pessoaId: input.personId,
projetoPessoaEnvolvidaVeiculoApiModel: this.vehicleApiMapper.mapDomainToApiModel(input.vehicle),
})
}
export class CDUpdateVehicleApiMapper implements ApiAdapter<UpdateCDVehicle['Input'], AtualizarVeiculoPessoaEnvolvidaRequest> {
private vehicleApiMapper: VehicleApiMapper
constructor() {
this.vehicleApiMapper = new VehicleApiMapper()
}
public mapDomainToApiModel = (input: UpdateCDVehicle['Input']): AtualizarVeiculoPessoaEnvolvidaRequest => ({
projetoId: input.projectId,
pessoaId: input.personId,
veiculoId: input.vehicleId,
projetoPessoaEnvolvidaVeiculoApiModel: this.vehicleApiMapper.mapDomainToApiModel(input.vehicle),
})
}
import { BDIdentification, Document } from '@agiliza/api/domain'
import { DadosNegocioIdentificacaoApiModel, DocumentoApiModel } from '@microcredito/client'
import { BDIdentification, BDProductService, Document } from '@agiliza/api/domain'
import {
DadosNegocioIdentificacaoApiModel,
DadosNegocioProdutoServicoApiModel,
DocumentoApiModel
} from '@microcredito/client'
import { DomainAdapter } from '../shared'
......@@ -37,3 +41,18 @@ export class BDIdentificationMapper implements DomainAdapter<DadosNegocioIdentif
document: dnIdent.documento ? this.documentAdapter.mapApiModelToDomain(dnIdent.documento) : undefined,
})
}
export class BDProductsServicesMapper implements DomainAdapter<DadosNegocioProdutoServicoApiModel, BDProductService> {
public mapPriceAmountToDomain = (pA: DadosNegocioProdutoServicoApiModel['custosVariaveis']) => ({
price: Number(pA?.precoUnitario).toFixed(2),
amount: pA?.quantidade?.toString() || '',
})
public mapApiModelToDomain = (pS: DadosNegocioProdutoServicoApiModel): BDProductService => ({
id: pS.id || '',
description: pS.descricao || '',
unit: pS.unidade || '',
monthlySales: pS.vendasMensais ? this.mapPriceAmountToDomain(pS.vendasMensais) : { amount: '', price: '' },
stock: pS.estoque ? this.mapPriceAmountToDomain(pS.estoque) : { amount: '', price: '' },
variableCosts: pS.custosVariaveis ? this.mapPriceAmountToDomain(pS.custosVariaveis) : { amount: '', price: '' },
})
}
......@@ -3,7 +3,10 @@ import {
EnquadramentoApiModel,
EscolaridadeApiModel,
EstadoCivilApiModel,
GeneroApiModel
GeneroApiModel,
RegistroEscrituraApiModel,
TipoMoradiaApiModel,
TipoReferenciaApiModel
} from '@microcredito/client'
import { DomainAdapter, IdDescriptionMapper } from '../shared'
......@@ -13,6 +16,9 @@ export interface DadosPropostaContexto {
generos: GeneroApiModel[]
escolaridades: EscolaridadeApiModel[]
estadosCivis: EstadoCivilApiModel[]
tiposReferencia: TipoReferenciaApiModel[]
registrosEscritura: RegistroEscrituraApiModel[]
tiposMoradia: TipoMoradiaApiModel[]
}
export class ContextMapper implements DomainAdapter<DadosPropostaContexto, ProposalDataContext> {
......@@ -26,5 +32,8 @@ export class ContextMapper implements DomainAdapter<DadosPropostaContexto, Propo
genders: dP.generos.map(this.idDescriptionMapper.mapApiModelToDomain),
schoolings: dP.escolaridades.map(this.idDescriptionMapper.mapApiModelToDomain),
maritalStatus: dP.estadosCivis.map(this.idDescriptionMapper.mapApiModelToDomain),
referenceTypes: dP.tiposReferencia.map(this.idDescriptionMapper.mapApiModelToDomain),
homeTypes: dP.tiposMoradia.map(this.idDescriptionMapper.mapApiModelToDomain),
deedRecords: dP.registrosEscritura.map(this.idDescriptionMapper.mapApiModelToDomain),
})
}
import {
Address,
Home,
InvolvedPerson,
IPAddress,
PersonalData,
Reference,
RG,
SourceIncome,
UpdateCDSpouseData,
Vehicle,
Workplace
} from '@agiliza/api/domain'
import {
......@@ -13,11 +16,14 @@ import {
ProjetoPessoaEnvolvidaConjugeApiModel,
ProjetoPessoaEnvolvidaConjugeDadosAdicionaisApiModel,
ProjetoPessoaEnvolvidaConjugeDadosAdicionaisLocalTrabalhoApiModel,
ProjetoPessoaEnvolvidaDadosMoradiaApiModel,
ProjetoPessoaEnvolvidaDadosPessoaisApiModel,
ProjetoPessoaEnvolvidaEnderecoApiModel,
ProjetoPessoaEnvolvidaFonteRendaApiModel,
ProjetoPessoaEnvolvidaIdentificacaoApiModel,
ProjetoPessoaEnvolvidaRGApiModel
ProjetoPessoaEnvolvidaReferenciaApiModel,
ProjetoPessoaEnvolvidaRGApiModel,
ProjetoPessoaEnvolvidaVeiculoApiModel
} from '@microcredito/client'
import { DomainAdapter } from '../shared'
......@@ -63,10 +69,10 @@ export class CDIdentificationAdapter implements DomainAdapter<ProjetoPessoaEnvol
export class RGMapper implements DomainAdapter<ProjetoPessoaEnvolvidaRGApiModel, RG> {
public mapApiModelToDomain = (rg: ProjetoPessoaEnvolvidaRGApiModel): RG => ({
back: rg.verso ?? '',
front: rg.frente ?? '',
number: rg.numero ?? '',
dispatcherAgency: rg.orgaoExpedidor ?? '',
back: rg.verso || '',
front: rg.frente || '',
number: rg.numero || '',
dispatcherAgency: rg.orgaoExpedidor || '',
})
}
......@@ -168,3 +174,50 @@ export class CDUpdateSpouseDataMapper implements DomainAdapter<ProjetoPessoaEnvo
workplace: pessoa.localTrabalho ? this.workspaceMapper.mapApiModelToDomain(pessoa.localTrabalho) : undefined,
})
}
export class ReferenceMapper implements DomainAdapter<ProjetoPessoaEnvolvidaReferenciaApiModel, Reference> {
public mapApiModelToDomain = (ref: ProjetoPessoaEnvolvidaReferenciaApiModel): Reference => ({
concept: ref.conceito || '',
extraInfo: ref.outrasInformacoes || '',
id: ref.id || '',
name: ref.nome || '',
photo: ref.foto ? ref.foto : '',
telephone: ref.telefone || '',
type: ref.tipo ? ref.tipo.toString() : '',
})
}
export class CDUpdateHomeMapper implements DomainAdapter<ProjetoPessoaEnvolvidaDadosMoradiaApiModel, Home> {
private addressAdapter: AddressMapper
constructor() {
this.addressAdapter = new AddressMapper()
}
public mapApiModelToDomain = (moradia: ProjetoPessoaEnvolvidaDadosMoradiaApiModel): Home => ({
address: moradia.endereco
? this.addressAdapter.mapApiModelToDomain(moradia.endereco)
: { id: '', cep: '', city: '', complement: '', district: '', number: '', state: '', street: '' },
cityResideTime: (moradia.tempoMunicipio && moradia.tempoMunicipio.toString()) || '',
deed: moradia.escritura || '',
deedRecord: (moradia.registroEscritura && moradia.registroEscritura.toString()) || '',
hasOnus: moradia.possuiOnus || false,
marketValue: (moradia.valorMercado && moradia.valorMercado.toFixed(2)) || '',
reside: moradia.resideImovel || false,
resideTime: (moradia.tempoLocal && moradia.tempoLocal.toString()) || '',
type: (moradia.tipo && moradia.tipo.toString()) || '',
proof: '',
})
}
export class VehicleMapper implements DomainAdapter<ProjetoPessoaEnvolvidaVeiculoApiModel, Vehicle> {
public mapApiModelToDomain = (vcl: ProjetoPessoaEnvolvidaVeiculoApiModel): Vehicle => ({
id: vcl.id || '',
document: vcl.documento || '',
hasInsurance: vcl.possuiSeguro || false,
hasOnus: vcl.possuiOnus || false,
licensePlate: vcl.placa || '',
marketValue: vcl.valorMercado ? vcl.valorMercado.toFixed(2) : '',
model: vcl.modelo || '',
brand: vcl.marca || '',
year: vcl.ano ? vcl.ano.toString() : '',
})
}
......@@ -10,8 +10,8 @@ interface IdDescription extends Entity {
}
export class IdDescriptionMapper implements DomainAdapter<IdDescricao, IdDescription> {
public mapApiModelToDomain = (iD: IdDescricao): IdDescription => ({
id: iD.id,
description: iD.descricao,
public mapApiModelToDomain = (iD: Partial<IdDescricao>): IdDescription => ({
id: iD.id || '',
description: iD.descricao || '',
})
}
import { mapUserAgentToString, SESSION_KEY, UserAgent } from '../shared'
import {
AddBDProductService,
GetBDProductsServices,
UpdateBDProductService
} from '@agiliza/api/domain'
import { ErrorMappers } from '@agiliza/api/mappers'
import { ClienteApi, Configuration } from '@microcredito/client'
export interface PDBusinessDataRepository {}
import { ProposalDataApiMappers, ProposalDataMappers } from '../../mappers'
import { API_URL, mapUserAgentToString, SESSION_KEY, UserAgent } from '../shared'
export interface PDBusinessDataRepository {
getProductsServices(input: GetBDProductsServices['Input']): Promise<GetBDProductsServices['Output']>
addProductService(input: AddBDProductService['Input']): Promise<AddBDProductService['Output']>
updateProductService(input: UpdateBDProductService['Input']): Promise<UpdateBDProductService['Output']>
}
export class PDBusinessDataRepositoryImpl implements PDBusinessDataRepository {
// private api: ClienteApi
// private errorAdapter: ErrorMappers.ResponseErrorAdapter
private api: ClienteApi
private errorAdapter: ErrorMappers.ResponseErrorAdapter
private bdGetServicesProductsMapper: ProposalDataMappers.BDProductsServicesMapper
private bdAddProductServiceApiMapper: ProposalDataApiMappers.BDAddProductServiceApiMapper
private bdUpdateProductServiceApiMapper: ProposalDataApiMappers.BDUpdateProductServiceApiMapper
constructor(userAgent: string, accessToken: string) {
// this.errorAdapter = new ErrorMappers.ResponseErrorAdapter()
// this.api = new ClienteApi(
// new Configuration({
// basePath: API_URL,
// accessToken,
// headers: {
// 'User-Agent': userAgent,
// },
// })
// )
this.errorAdapter = new ErrorMappers.ResponseErrorAdapter()
this.bdGetServicesProductsMapper = new ProposalDataMappers.BDProductsServicesMapper()
this.bdAddProductServiceApiMapper = new ProposalDataApiMappers.BDAddProductServiceApiMapper()
this.bdUpdateProductServiceApiMapper = new ProposalDataApiMappers.BDUpdateProductServiceApiMapper()
this.api = new ClienteApi(
new Configuration({
basePath: API_URL,
accessToken,
headers: {
'User-Agent': userAgent,
},
})
)
}
public getProductsServices = async (input: GetBDProductsServices['Input']): Promise<GetBDProductsServices['Output']> => {
try {
const response = await this.api.obterProdutosServicosDadosNegocio({ projetoId: input.projectId })
return response.map(this.bdGetServicesProductsMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public addProductService = async (input: AddBDProductService['Input']): Promise<AddBDProductService['Output']> => {
try {
const response = await this.api.criarProdutoServicoDadosNegocio(this.bdAddProductServiceApiMapper.mapDomainToApiModel(input))
return response.map(this.bdGetServicesProductsMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public updateProductService = async (input: UpdateBDProductService['Input']): Promise<UpdateBDProductService['Output']> => {
try {
const response = await this.api.atualizaProdutoServicoDadosNegocio(this.bdUpdateProductServiceApiMapper.mapDomainToApiModel(input))
return response.map(this.bdGetServicesProductsMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
}
......
......@@ -36,6 +36,9 @@ export class ProposalDataContextRepositoryImpl implements ProposalDataContextRep
generos: await this.api.obterGeneros(),
escolaridades: await this.api.obterEscolaridades(),
estadosCivis: await this.api.obterEstadosCivis(),
tiposReferencia: await this.api.obterTiposReferencia(),
tiposMoradia: await this.api.obterTiposMoradia(),
registrosEscritura: await this.api.obterRegistrosEscritura(),
}
return this.contextMapper.mapApiModelToDomain(contexto)
} catch (e) {
......
import {
AddCDIdentification,
AddCDReference,
AddCDVehicle,
CreateProposal,
GetCDReferences,
GetCDVehicles,
UpdateCDAddress,
UpdateCDHome,
UpdateCDPersonalData,
UpdateCDReference,
UpdateCDSourceIncome,
UpdateCDSpouseData
UpdateCDSpouseData,
UpdateCDVehicle
} from '@agiliza/api/domain'
import { ClienteApi, Configuration } from '@microcredito/client'
......@@ -18,6 +25,13 @@ export interface PDCustomerDataDataRepository {
updateAddress(input: UpdateCDAddress['Input']): Promise<UpdateCDAddress['Output']>
updateSourceIncome(input: UpdateCDSourceIncome['Input']): Promise<UpdateCDSourceIncome['Output']>
updateSpouseData(input: UpdateCDSpouseData['Input']): Promise<UpdateCDSpouseData['Output']>
getReferences(input: GetCDReferences['Input']): Promise<GetCDReferences['Output']>
addReference(input: AddCDReference['Input']): Promise<AddCDReference['Output']>
updateReference(input: UpdateCDReference['Input']): Promise<UpdateCDReference['Output']>
updateHome(input: UpdateCDHome['Input']): Promise<UpdateCDHome['Output']>
getVehicles(input: GetCDVehicles['Input']): Promise<GetCDVehicles['Output']>
addVehicle(input: AddCDVehicle['Input']): Promise<AddCDVehicle['Output']>
updateVehicle(input: UpdateCDVehicle['Input']): Promise<UpdateCDVehicle['Output']>
}
export class PDCustomerDataRepositoryImpl implements PDCustomerDataDataRepository {
......@@ -34,6 +48,14 @@ export class PDCustomerDataRepositoryImpl implements PDCustomerDataDataRepositor
private cdUpdateSourceIncomeMapper: ProposalDataMappers.CDSourceIncomeAdapter
private cdUpdateSpouseDataApiMapper: ProposalDataApiMappers.CDUpdateSpouseDataApiMapper
private cdUpdateSpouseDataMapper: ProposalDataMappers.CDUpdateSpouseDataMapper
private cdReferenceMapper: ProposalDataMappers.ReferenceMapper
private cdAddReferenceApiMapper: ProposalDataApiMappers.CDAddReferenceApiMapper
private cdUpdateReferenceApiMapper: ProposalDataApiMappers.CDUpdateReferenceApiMapper
private cdUpdateHomeApiMapper: ProposalDataApiMappers.CDUpdateHomeApiMapper
private cdUpdateHomeMapper: ProposalDataMappers.CDUpdateHomeMapper
private cdVehicleMapper: ProposalDataMappers.VehicleMapper
private cdAddVehicleApiMapper: ProposalDataApiMappers.CDAddVehicleApiMapper
private cdUpdateVehicleApiMapper: ProposalDataApiMappers.CDUpdateVehicleApiMapper
constructor(userAgent: string, accessToken: string) {
this.errorAdapter = new ErrorMappers.ResponseErrorAdapter()
......@@ -48,6 +70,14 @@ export class PDCustomerDataRepositoryImpl implements PDCustomerDataDataRepositor
this.cdUpdateSourceIncomeMapper = new ProposalDataMappers.CDSourceIncomeAdapter()
this.cdUpdateSpouseDataApiMapper = new ProposalDataApiMappers.CDUpdateSpouseDataApiMapper()
this.cdUpdateSpouseDataMapper = new ProposalDataMappers.CDUpdateSpouseDataMapper()
this.cdReferenceMapper = new ProposalDataMappers.ReferenceMapper()
this.cdAddReferenceApiMapper = new ProposalDataApiMappers.CDAddReferenceApiMapper()
this.cdUpdateReferenceApiMapper = new ProposalDataApiMappers.CDUpdateReferenceApiMapper()
this.cdUpdateHomeApiMapper = new ProposalDataApiMappers.CDUpdateHomeApiMapper()
this.cdUpdateHomeMapper = new ProposalDataMappers.CDUpdateHomeMapper()
this.cdVehicleMapper = new ProposalDataMappers.VehicleMapper()
this.cdAddVehicleApiMapper = new ProposalDataApiMappers.CDAddVehicleApiMapper()
this.cdUpdateVehicleApiMapper = new ProposalDataApiMappers.CDUpdateVehicleApiMapper()
this.api = new ClienteApi(
new Configuration({
......@@ -119,6 +149,76 @@ export class PDCustomerDataRepositoryImpl implements PDCustomerDataDataRepositor
throw result
}
}
public getReferences = async (input: GetCDReferences['Input']): Promise<GetCDReferences['Output']> => {
try {
const response = await this.api.obterReferenciasPessoaEnvolvida({ pessoaId: input.personId, projetoId: input.projectId })
return response.map(this.cdReferenceMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public addReference = async (input: AddCDReference['Input']): Promise<AddCDReference['Output']> => {
try {
const response = await this.api.criarReferenciaPessoaEnvolvida(this.cdAddReferenceApiMapper.mapDomainToApiModel(input))
return response.map(this.cdReferenceMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public updateReference = async (input: UpdateCDReference['Input']): Promise<UpdateCDReference['Output']> => {
try {
const response = await this.api.atualiarReferenciaPessoaEnvolvida(this.cdUpdateReferenceApiMapper.mapDomainToApiModel(input))
return response.map(this.cdReferenceMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public updateHome = async (input: UpdateCDHome['Input']): Promise<UpdateCDHome['Output']> => {
try {
const response = await this.api.atualizarDadosMoradiaPessoaEnvolvida(this.cdUpdateHomeApiMapper.mapDomainToApiModel(input))
return this.cdUpdateHomeMapper.mapApiModelToDomain(response)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public getVehicles = async (input: GetCDVehicles['Input']): Promise<GetCDVehicles['Output']> => {
try {
const response = await this.api.obterVeiculosPessoaEnvolvida({ projetoId: input.projectId, pessoaId: input.personId })
return response.map(this.cdVehicleMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public addVehicle = async (input: AddCDVehicle['Input']): Promise<AddCDVehicle['Output']> => {
try {
const response = await this.api.criarVeiculoPessoaEnvolvida(this.cdAddVehicleApiMapper.mapDomainToApiModel(input))
return response.map(this.cdVehicleMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
public updateVehicle = async (input: UpdateCDVehicle['Input']): Promise<UpdateCDVehicle['Output']> => {
try {
const response = await this.api.atualizarVeiculoPessoaEnvolvida(this.cdUpdateVehicleApiMapper.mapDomainToApiModel(input))
return response.map(this.cdVehicleMapper.mapApiModelToDomain)
} catch (e) {
const result = await this.errorAdapter.mapApiModelToDomain(e)
throw result
}
}
}
export class PDCustomerDataRepositoryImplFactory {
......
......@@ -26,7 +26,7 @@ const ImageUpload = (props: Props) => {
<Button variant="text" component="label" className={cn(classes.photoBtn, buttonClassName)} classes={{ label: classes.photoLabelBtn }}>
{image ? (
<div className={classes.card} style={imageStyle}>
<img src={image} className={classes.media} />
<img src={'data:image/png;base64,' + image} className={classes.media} />
</div>
) : (
<PhotoCameraIcon />
......
......@@ -2,7 +2,7 @@ import React from 'react'
import { BanestesAccount } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import { extractNumbers } from '@agiliza/utils/method'
import { extractNumbers, getBase64FromFile } from '@agiliza/utils/method'
import { TextField, TextFieldProps } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
......@@ -28,12 +28,7 @@ const AccountInputsPhoto = (props: Props) => {
const handleChangePhoto: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
})
const b64: string = await getBase64FromFile(file)
onChanges.photo(b64)
}
}
......
......@@ -3,6 +3,7 @@ import React from 'react'
import { RG } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import { maskRG } from '@agiliza/utils/masks'
import { getBase64FromFile } from '@agiliza/utils/method'
import { TextField, TextFieldProps } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
......@@ -23,12 +24,7 @@ const RGTemplate = (props: Props) => {
async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64 = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
const b64 = await getBase64FromFile(file)
onChange({ [key]: b64 })
}
}
......
......@@ -14,6 +14,9 @@ export const initialState: Store = {
genders: { byId: {}, allIds: [] },
schoolings: { byId: {}, allIds: [] },
maritalStatus: { byId: {}, allIds: [] },
referenceTypes: { byId: {}, allIds: [] },
homeTypes: { byId: {}, allIds: [] },
deedRecords: { byId: {}, allIds: [] },
}
export default createSlice({
......
......@@ -2,3 +2,6 @@ import { Store } from './slice'
export const getProposalId = (state: Store) => state.proposalId
export const getPersonlId = (state: Store) => state.personId
export const getReferences = (state: Store) => state.references
export const getVehicles = (state: Store) => state.vehicles
export const getProductsServices = (state: Store) => state.productsServices
import { Identification } from '@agiliza/api/domain'
import { types as fetchTypes } from '@agiliza/redux/useCases/proposalData/customerData'
import {
AddBDProductService,
AddCDReference,
AddCDVehicle,
BDProductService,
GetBDProductsServices,
GetCDReferences,
GetCDVehicles,
Identification,
Reference,
UpdateBDProductService,
UpdateCDReference,
UpdateCDVehicle,
Vehicle
} from '@agiliza/api/domain'
import { types as businessDataTypes } from '@agiliza/redux/useCases/proposalData/businessData'
import { types as customerDataTypes } from '@agiliza/redux/useCases/proposalData/customerData'
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { PROPOSAL_DATA_PREFIX } from '../shared'
......@@ -7,11 +22,17 @@ import { PROPOSAL_DATA_PREFIX } from '../shared'
export interface Store {
proposalId: string
personId: string
references: Reference[]
vehicles: Vehicle[]
productsServices: BDProductService[]
}
export const initialState: Store = {
proposalId: '',
personId: '',
references: [],
vehicles: [],
productsServices: [],
}
export default createSlice({
......@@ -19,11 +40,38 @@ export default createSlice({
initialState,
reducers: {},
extraReducers: {
[fetchTypes.createProposal.fulfilled]: (state, action: PayloadAction<string>) => {
[customerDataTypes.createProposal.fulfilled]: (state, action: PayloadAction<string>) => {
state.proposalId = action.payload
},
[fetchTypes.addIndentification.fulfilled]: (state, action: PayloadAction<Identification>) => {
[customerDataTypes.addIndentification.fulfilled]: (state, action: PayloadAction<Identification>) => {
state.personId = action.payload.id
},
[customerDataTypes.getReferences.fulfilled]: (state, action: PayloadAction<GetCDReferences['Output']>) => {
state.references = action.payload
},
[customerDataTypes.addReference.fulfilled]: (state, action: PayloadAction<AddCDReference['Output']>) => {
state.references = action.payload
},
[customerDataTypes.updateReference.fulfilled]: (state, action: PayloadAction<UpdateCDReference['Output']>) => {
state.references = action.payload
},
[customerDataTypes.getVehicles.fulfilled]: (state, action: PayloadAction<GetCDVehicles['Output']>) => {
state.vehicles = action.payload
},
[customerDataTypes.addVehicle.fulfilled]: (state, action: PayloadAction<AddCDVehicle['Output']>) => {
state.vehicles = action.payload
},
[customerDataTypes.updateVehicle.fulfilled]: (state, action: PayloadAction<UpdateCDVehicle['Output']>) => {
state.vehicles = action.payload
},
[businessDataTypes.getProductsServices.fulfilled]: (state, action: PayloadAction<GetBDProductsServices['Output']>) => {
state.productsServices = action.payload
},
[businessDataTypes.addProductService.fulfilled]: (state, action: PayloadAction<AddBDProductService['Output']>) => {
state.productsServices = action.payload
},
[businessDataTypes.updateProductService.fulfilled]: (state, action: PayloadAction<UpdateBDProductService['Output']>) => {
state.productsServices = action.payload
},
},
})
......@@ -7,12 +7,15 @@ export const PROPOSAL_DATA_PREFIX = 'entities/proposalData'
export type NormalizedContext = WithNormalizedEntity<ProposalDataContext>
const contextSchemas = new schema.Object({
const contextSchemas: Record<keyof ProposalDataContext, any> = {
frameworks: new schema.Array(new schema.Entity('frameworks')),
genders: new schema.Array(new schema.Entity('genders')),
schoolings: new schema.Array(new schema.Entity('schoolings')),
maritalStatus: new schema.Array(new schema.Entity('maritalStatus')),
})
referenceTypes: new schema.Array(new schema.Entity('referenceTypes')),
homeTypes: new schema.Array(new schema.Entity('homeTypes')),
deedRecords: new schema.Array(new schema.Entity('deedRecords')),
}
export const normalizeContext = (context: ProposalDataContext) => {
const { entities } = normalize(context, contextSchemas)
......
import { createAsyncReducers, getTypesThunkActions, values } from '@agiliza/utils/method'
import { createSlice } from '@reduxjs/toolkit'
import {
AddBDProductService,
GetBDProductsServices,
UpdateBDProductService
} from '@agiliza/api/domain'
import { PDBusinessDataRepositoryImplFactory } from '@agiliza/api/useCases'
import { appPlatform } from '@agiliza/constants/platform'
import {
createAsyncReducers,
getTypesThunkActions,
values,
WithSuccess
} from '@agiliza/utils/method'
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
const prefix = 'useCases/businessData'
......@@ -11,7 +23,38 @@ export const initialState: State = {
fetching: false,
}
export const actions = {} as const
export const actions = {
getProductsServices: createAsyncThunk(`${prefix}/getProductsServices`, async (input: WithSuccess<GetBDProductsServices['Input']>, thunkApi) => {
const useCase = PDBusinessDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.getProductsServices(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
addProductService: createAsyncThunk(`${prefix}/addProductService`, async (input: WithSuccess<AddBDProductService['Input']>, thunkApi) => {
const useCase = PDBusinessDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.addProductService(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
updateProductService: createAsyncThunk(`${prefix}/updateProductService`, async (input: WithSuccess<UpdateBDProductService['Input']>, thunkApi) => {
const useCase = PDBusinessDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.updateProductService(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
} as const
export const types = getTypesThunkActions(actions)
const login = createSlice({
......
import {
AddCDIdentification,
AddCDReference,
AddCDVehicle,
CreateProposal,
GetCDReferences,
GetCDVehicles,
UpdateCDAddress,
UpdateCDHome,
UpdateCDPersonalData,
UpdateCDReference,
UpdateCDSourceIncome,
UpdateCDSpouseData
UpdateCDSpouseData,
UpdateCDVehicle
} from '@agiliza/api/domain'
import {
PDCustomerDataRepositoryImplFactory
......@@ -32,9 +39,9 @@ export const actions = {
createProposal: createAsyncThunk(`${prefix}/createProposal`, async (input: WithSuccess<CreateProposal['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const proposalId = await useCase.createProposal(input)
const response = await useCase.createProposal(input)
input.onSuccess && input.onSuccess()
return proposalId
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
......@@ -52,9 +59,9 @@ export const actions = {
updatePersonalData: createAsyncThunk(`${prefix}/updatePersonalData`, async (input: WithSuccess<UpdateCDPersonalData['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const proposalId = await useCase.updatePersonalData(input)
const response = await useCase.updatePersonalData(input)
input.onSuccess && input.onSuccess()
return proposalId
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
......@@ -62,9 +69,9 @@ export const actions = {
updateAddress: createAsyncThunk(`${prefix}/updateAddress`, async (input: WithSuccess<UpdateCDAddress['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const proposalId = await useCase.updateAddress(input)
const response = await useCase.updateAddress(input)
input.onSuccess && input.onSuccess()
return proposalId
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
......@@ -72,19 +79,89 @@ export const actions = {
updateSourceIncome: createAsyncThunk(`${prefix}/updateSourceIncome`, async (input: WithSuccess<UpdateCDSourceIncome['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const proposalId = await useCase.updateSourceIncome(input)
const response = await useCase.updateSourceIncome(input)
input.onSuccess && input.onSuccess()
return proposalId
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
updateSpouseData: createAsyncThunk(`${prefix}/updateSourceIncome`, async (input: WithSuccess<UpdateCDSpouseData['Input']>, thunkApi) => {
updateSpouseData: createAsyncThunk(`${prefix}/updateSpouseData`, async (input: WithSuccess<UpdateCDSpouseData['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const proposalId = await useCase.updateSpouseData(input)
const response = await useCase.updateSpouseData(input)
input.onSuccess && input.onSuccess()
return proposalId
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
getReferences: createAsyncThunk(`${prefix}/getReferences`, async (input: WithSuccess<GetCDReferences['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.getReferences(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
addReference: createAsyncThunk(`${prefix}/addReference`, async (input: WithSuccess<AddCDReference['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.addReference(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
updateReference: createAsyncThunk(`${prefix}/updateReference`, async (input: WithSuccess<UpdateCDReference['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.updateReference(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
updateHome: createAsyncThunk(`${prefix}/updateHome`, async (input: WithSuccess<UpdateCDHome['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.updateHome(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
getVehicles: createAsyncThunk(`${prefix}/getVehicles`, async (input: WithSuccess<GetCDVehicles['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.getVehicles(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
addVehicle: createAsyncThunk(`${prefix}/addVehicle`, async (input: WithSuccess<AddCDVehicle['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.addVehicle(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}),
updateVehicle: createAsyncThunk(`${prefix}/updateVehicle`, async (input: WithSuccess<UpdateCDVehicle['Input']>, thunkApi) => {
const useCase = PDCustomerDataRepositoryImplFactory.create(appPlatform)
try {
const response = await useCase.updateVehicle(input)
input.onSuccess && input.onSuccess()
return response
} catch (e) {
return thunkApi.rejectWithValue(e)
}
......
......@@ -212,3 +212,12 @@ export const b64toBlob = (b64Data: string, contentType = '', sliceSize = 512) =>
const blob = new Blob(byteArrays, { type: contentType })
return blob
}
export const getBase64FromFile = async (file: File): Promise<string> => {
return await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve((reader.result as string)?.split(',')[1] || '')
reader.onerror = (error) => reject(error)
})
}
......@@ -51,7 +51,7 @@ const Main = (props: Props) => {
path={PATHS.proposalData}
render={(rProps) => {
const { location } = rProps as RouteComponentProps<any, any, ProposalDataRouteState>
if (!location.state) location.state = { subproductId: '0' }
// if (!location.state) location.state = { subproductId: '0' }
if (location.state?.subproductId) return <ProposalData {...rProps} />
else return <Redirect from={PATHS.proposalData} to="/" />
}}
......
......@@ -26,7 +26,6 @@ const Address = (props: Props) => {
(evt) => {
onChange({ [key]: evt.target.value })
}
return (
<>
<TextField variant="outlined" label="CEP" value={maskCEP(cep)} onChange={handleChangeText('cep')} inputProps={{ maxLength: 9 }} />
......
import React from 'react'
import { extractNumbers } from '@agiliza/utils/extractors'
import { formatCurrency } from '@agiliza/utils/formatters'
import { TextField, TextFieldProps } from '@material-ui/core'
const getTotalPrice = <T extends { price: string; amount: string }>(pva: T) => {
const { amount, price } = pva
return price && amount ? (Number(extractNumbers(price)) * Number(amount)).toString() : ''
}
type ExtendedProps = Record<string, unknown>
export interface Values {
price: string
amount: string
}
interface Props extends ExtendedProps {
values: Values
onChange: (value: Partial<Values>) => void
}
const PriceAmountInput = (props: Props) => {
const { values, onChange } = props
const { price, amount } = values
const handleChangeText =
(key: keyof Values): TextFieldProps['onChange'] =>
(evt) => {
onChange({ [key]: evt.target.value })
}
return (
<>
<TextField variant="outlined" label="Preço unitário" value={formatCurrency(price)} onChange={handleChangeText('price')} />
<TextField variant="outlined" label="Qtde" value={amount} onChange={handleChangeText('amount')} />
<TextField disabled variant="outlined" label="Valor total" value={formatCurrency(getTotalPrice(values))} />
</>
)
}
export default PriceAmountInput
export { default } from './PriceAmountInput'
export * from './PriceAmountInput'
import React, { ChangeEvent, useState } from 'react'
import React from 'react'
import { RouteComponentProps } from 'react-router'
import { Tab } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import {
AccountBox as AccountBoxIcon,
Apartment as ApartmentIcon,
AttachMoney as AttachMoneyIcon,
InsertDriveFile as InsertDriveFileIcon
} from '@material-ui/icons'
import { TabContext, TabList, TabPanel } from '@material-ui/lab'
import Address from './Address'
import Identification from './Identification'
import ProductsServices from './ProductsServices'
import StockSalesCosts from './StockSalesCosts'
import styles from './styles'
export const businessDataItems = [
{ label: 'Identificação', icon: <AccountBoxIcon />, component: <Identification /> },
{ label: 'Endereço', icon: <ApartmentIcon />, component: <Address /> },
{ label: 'Estoque, Vendas e Custos', icon: <AttachMoneyIcon />, component: <StockSalesCosts /> },
{ label: 'Produto', icon: <InsertDriveFileIcon />, component: <ProductsServices /> },
]
type ExtendedProps = WithStyles<typeof styles> & RouteComponentProps
interface Props extends ExtendedProps {}
const BusinessData = (props: Props) => {
const { classes } = props
const [tab, setTab] = useState('0')
const handleChange = (evt: ChangeEvent<Record<string, unknown>>, newValue: number) => {
setTab(newValue.toString())
}
return (
<div className={classes.contentContainer}>
{/* <div className={classes.breadcrumbsContainer}>
<Breadcrumbs aria-label="breadcrumb">
<Link color="inherit" href="/" onClick={() => history.push(PATHS.proposalData)}>
Dados Proposta
</Link>
<Link href="/" color="textPrimary" onClick={() => history.push(PATHS.proposalData + PROPOSAL_DATA_PATHS.businessData)}>
Dados Negócio
</Link>
</Breadcrumbs>
</div> */}
<div className={classes.tabsContainer}>
<TabContext value={tab}>
<TabList
orientation="vertical"
variant="scrollable"
value={tab}
onChange={handleChange}
aria-label="Vertical tabs example"
className={classes.tabs}
>
{businessDataItems.map(({ component, ...tb }, i) => (
<Tab wrapped key={i} {...tb} value={i.toString()} />
))}
</TabList>
<div className={classes.content}>
{businessDataItems.map((tb, i) => (
<TabPanel key={i} value={i.toString()}>
{tb.component}
</TabPanel>
))}
</div>
</TabContext>
</div>
</div>
)
return <div className={classes.contentContainer}></div>
}
export default withStyles(styles)(BusinessData)
......@@ -21,7 +21,7 @@ type ExtendedProps = Pick<DialogProps, 'open'> & WithStyles<typeof styles>
interface Props extends ExtendedProps {
onClose: () => void
productService?: BDProductService
onSave(rfc: BDProductService): () => void
onSave(rfc: BDProductService, add: boolean): () => void
}
const Dialog = (props: Props) => {
......@@ -48,7 +48,7 @@ const Dialog = (props: Props) => {
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancelar</Button>
<Button onClick={onSave(mapStateToProductService())}>Salvar</Button>
<Button onClick={onSave(mapStateToProductService(), !productService)}>Salvar</Button>
</DialogActions>
</MUIDialog>
)
......
......@@ -7,6 +7,6 @@ import sharedStyles from '../styles'
export default (theme: Theme) => {
return createStyles({
...sharedStyles(theme),
dialog: { height: '40%', width: '40%' },
dialog: { width: '80%', height: '55%' },
})
}
import React from 'react'
import { extractNumbers } from '@agiliza/utils/extractors'
import { ActionType } from '@agiliza/utils/hooks/state'
import { TextField, TextFieldProps } from '@material-ui/core'
import PriceAmountInput, {
Values
} from '@agiliza/views/ProposalData/components/templates/PriceAmountInput'
import { TextField, TextFieldProps, Typography } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { BDProductServiceState } from '../state'
......@@ -17,7 +21,7 @@ interface Props extends ExtendedProps {
const Form = (props: Props) => {
const { classes, state, actions } = props
const { description, unit } = state
const { description, unit, stock, monthlySales, variableCosts } = state
const handleChangeText =
(key: keyof BDProductServiceState): TextFieldProps['onChange'] =>
......@@ -25,10 +29,20 @@ const Form = (props: Props) => {
actions.update({ [key]: evt.target.value })
}
const handleChangePriceAmount = (keyState: keyof BDProductServiceState) => (value: Partial<Values>) => {
actions.update({ [keyState]: value })
}
return (
<form className={classes.form}>
<TextField variant="outlined" label="Descrição do produto / serviço" value={description} onChange={handleChangeText('description')} />
<TextField variant="outlined" label="Placa" value={unit} onChange={handleChangeText('unit')} type="tel" />
<TextField variant="outlined" label="Unidade" value={extractNumbers(unit)} onChange={handleChangeText('unit')} type="tel" />
<Typography className={classes.label}>Informações de estoque</Typography>
<PriceAmountInput values={stock} onChange={handleChangePriceAmount('stock')} />
<Typography className={classes.label}>Vendas mensais</Typography>
<PriceAmountInput values={monthlySales} onChange={handleChangePriceAmount('monthlySales')} />
<Typography className={classes.label}>Custos variáveis</Typography>
<PriceAmountInput values={variableCosts} onChange={handleChangePriceAmount('variableCosts')} />
</form>
)
}
......
......@@ -19,5 +19,6 @@ export default (theme: Theme) => {
},
switchCardPhotoContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly' },
datePicker: { marginBottom: '0px !important' },
label: { marginBottom: theme.spacing(2) },
})
}
import React, { useState } from 'react'
import { productServices } from '@agiliza/__mocks__/proposalData/involvedPeople/productServices'
import { BDProductService } from '@agiliza/api/domain'
import { ActionType } from '@agiliza/utils/hooks/state'
import { Avatar, List, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { Add as AddIcon, Apps as AppsIcon } from '@material-ui/icons'
import { connected, ConnectedProps } from './connect'
import Dialog from './Dialog'
import { BDProductServiceState } from './state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
type ExtendedProps = WithStyles<typeof styles> & ConnectedProps
interface Props extends ExtendedProps {}
interface Props extends ExtendedProps {
projectId: string
state: BDProductServiceState
actions: ActionType<BDProductServiceState>
}
const ProductsServices = (props: Props) => {
const { classes } = props
const { classes, projectId, productsServices } = props
const [selectedProductService, setSelectedProductService] = useState<BDProductService | undefined>()
......@@ -30,14 +36,17 @@ const ProductsServices = (props: Props) => {
setSelectedProductService(undefined)
}
const handleSave = (vehicle: BDProductService) => () => {}
const handleSave = (productService: BDProductService, add: boolean) => () => {
if (add) props.addProductService({ projectId, productService, onSuccess: () => setOpen(false) })
else props.updateProductService({ projectId, productServiceId: productService.id, productService, onSuccess: () => setOpen(false) })
}
return (
<>
<div className={classes.contentContainer}>
<div className={classes.content}>
<List className={classes.list}>
{productServices.map((vehicle, i) => (
{productsServices.map((vehicle, i) => (
<ListItem key={i} button onClick={handleClickListItem(vehicle)}>
<ListItemAvatar>
<Avatar>
......@@ -58,4 +67,4 @@ const ProductsServices = (props: Props) => {
)
}
export default withStyles(styles)(ProductsServices)
export default connected(withStyles(styles)(ProductsServices))
import { connect } from 'react-redux'
import { bindActionCreators, Dispatch } from 'redux'
import { BDProductService, ProposalDataContext } from '@agiliza/api/domain'
import { StoreState } from '@agiliza/redux'
import * as entProposalDataContext from '@agiliza/redux/entities/proposalData/context'
import * as entProposalData from '@agiliza/redux/entities/proposalData/proposal'
import * as ucProposalData from '@agiliza/redux/useCases/proposalData/businessData'
import * as ucProposalDataContext from '@agiliza/redux/useCases/proposalData/context'
export interface ConnectedProps {
fetching: boolean
productsServices: BDProductService[]
getProductsServices: typeof ucProposalData.actions.getProductsServices
addProductService: typeof ucProposalData.actions.addProductService
updateProductService: typeof ucProposalData.actions.updateProductService
context: ProposalDataContext
}
type StateProps = Pick<ConnectedProps, 'fetching' | 'context' | 'productsServices'>
type DispatchProps = Pick<ConnectedProps, 'getProductsServices' | 'addProductService' | 'updateProductService'>
const mapStateToProps = (state: StoreState): StateProps => ({
fetching: ucProposalDataContext.selectors.isFetching(state.ui.login),
context: entProposalDataContext.selectors.getContext(state.entities.proposalData.context),
productsServices: entProposalData.selectors.getProductsServices(state.entities.proposalData.proposal),
})
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
bindActionCreators(
{
getProductsServices: ucProposalData.actions.getProductsServices,
addProductService: ucProposalData.actions.addProductService,
updateProductService: ucProposalData.actions.updateProductService,
},
dispatch
)
export const connected = connect(mapStateToProps, mapDispatchToProps)
export { default } from './ProductsServices'
export * from './ProductsServices'
export * from './state'
......@@ -4,10 +4,21 @@ type ExtendedState = BDProductService
export interface BDProductServiceState extends ExtendedState {}
export const initialState: BDProductServiceState = {
export const initialState: BDProductServiceState =
process.env.NODE_ENV === 'development'
? {
id: '',
description: 'TEST',
unit: '10',
monthlySales: { amount: '10', price: '2000' },
stock: { amount: '20', price: '3000' },
variableCosts: { amount: '30', price: '4000' },
}
: {
id: '',
description: '',
unit: '',
monthlySales: { amount: '', price: '' },
stock: { amount: '', price: '' },
variableCosts: { amount: '', price: '' },
}
}
......@@ -4,6 +4,7 @@ import { City, State } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import Address, { AddressState } from '@agiliza/components/templates/Address'
import { ActionType } from '@agiliza/utils/hooks/state'
import { getBase64FromFile } from '@agiliza/utils/method'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CDAddressState } from '../state'
......@@ -26,12 +27,7 @@ const Form = (props: Props) => {
const handleChangeProof: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
})
const b64: string = await getBase64FromFile(file)
actions.update({ proof: b64 })
}
}
......
import { file } from '@agiliza/__mocks__/files'
import { IPAddress } from '@agiliza/api/domain'
type ExtendedState = IPAddress
export interface CDAddressState extends ExtendedState {}
export const initialState: CDAddressState = {
export const initialState: CDAddressState =
process.env.NODE_ENV === 'development'
? { id: '', proof: file, cep: '29100100', city: '16', complement: 'TEST', district: 'TEST', number: '123', state: '1', street: 'TEST' }
: {
id: '',
proof: '',
cep: '',
......@@ -14,4 +18,4 @@ export const initialState: CDAddressState = {
number: '',
state: '',
street: '',
}
}
import React from 'react'
import { IPAddress } from '@agiliza/api/domain'
import { AuthenticationContext, IPAddress, ProposalDataContext } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import AddressTemplate from '@agiliza/components/templates/Address'
import { ActionType } from '@agiliza/utils/hooks/state'
import AddressTemplate from '@agiliza/views/ProposalData/components/templates/Address'
import { TextField, TextFieldProps } from '@material-ui/core'
import { extractNumbers, getBase64FromFile } from '@agiliza/utils/method'
import { SelectField, SelectFieldProps, Switch } from '@curio/components'
import {
Checkbox,
CheckboxProps,
FormControlLabel,
FormGroup,
TextField,
TextFieldProps
} from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CustomerHomeState } from '../state'
import { CDHomeState } from '../state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
interface Props extends ExtendedProps {
state: CustomerHomeState
actions: ActionType<CustomerHomeState>
addressContext: AuthenticationContext
state: CDHomeState
actions: ActionType<CDHomeState>
context: ProposalDataContext
}
const Form = (props: Props) => {
const { classes, state, actions } = props
const { resideTime, cityResideTime, address } = state
const { classes, addressContext, context, state, actions } = props
const { states, cities } = addressContext
const { resideTime, cityResideTime, address, hasProperty, deed, type, deedRecord, reside, hasOnus } = state
const handleChangeText =
(key: keyof CustomerHomeState): TextFieldProps['onChange'] =>
(key: keyof CDHomeState): TextFieldProps['onChange'] =>
(evt) => {
actions.update({ [key]: evt.target.value })
}
const handleChangeProof: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await getBase64FromFile(file)
actions.update({ deed: b64 })
}
}
const handleChangeSelect =
(key: keyof CDHomeState): SelectFieldProps['onChange'] =>
(vl) => {
actions.update({ [key]: vl })
}
const handleChangeCheckbox =
(key: keyof Pick<CDHomeState, 'reside' | 'hasOnus'>): CheckboxProps['onChange'] =>
(_, checked) => {
actions.update({ [key]: checked })
}
return (
<form className={classes.form}>
<TextField variant="outlined" label="Tempo (no local)" value={resideTime} onChange={handleChangeText('resideTime')} type="number" />
<TextField variant="outlined" label="Tempo (no município)" value={cityResideTime} onChange={handleChangeText('cityResideTime')} type="number" />
<AddressTemplate state={address} onChange={(addrs) => actions.update({ address: addrs as IPAddress })} />
<Switch label="Possui imóveis?" value={hasProperty} onChange={(vl) => actions.update({ hasProperty: vl })} required />
{hasProperty ? (
<>
<ImageUpload label="Escritura" image={deed} onChangeImage={handleChangeProof} className={classes.imageUpload} />
<SelectField
id="type-select-field"
label="Tipo"
value={type}
onChange={handleChangeSelect('type')}
items={context.homeTypes.map((hT) => ({ label: hT.description, value: hT.id }))}
variant="outlined"
shrink={false}
/>
<SelectField
id="deed-record-select-field"
label="Registro da escritura"
value={deedRecord}
onChange={handleChangeSelect('deedRecord')}
items={context.deedRecords.map((dR) => ({ label: dR.description, value: dR.id }))}
variant="outlined"
shrink={false}
/>
<FormGroup row className={classes.formGroup}>
<FormControlLabel
control={<Checkbox name="reside" checked={reside} onChange={handleChangeCheckbox('reside')} />}
label="Reside no imóvel?"
/>
<FormControlLabel
control={<Checkbox name="reside" checked={hasOnus} onChange={handleChangeCheckbox('hasOnus')} />}
label="Possui ônus?"
/>
</FormGroup>
<TextField
variant="outlined"
label="Tempo (no local)"
value={extractNumbers(resideTime)}
onChange={handleChangeText('resideTime')}
type="number"
/>
<TextField
variant="outlined"
label="Tempo (no município)"
value={extractNumbers(cityResideTime)}
onChange={handleChangeText('cityResideTime')}
type="number"
/>
<AddressTemplate states={states} cities={cities} state={address} onChange={(addrs) => actions.update({ address: addrs as IPAddress })} />
</>
) : null}
</form>
)
}
......
......@@ -7,7 +7,9 @@ import sharedStyles from '../styles'
export default (theme: Theme) => {
return createStyles({
...sharedStyles(theme),
switchCardPhotoContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly' },
formGroup: {
marginBottom: theme.spacing(2),
},
})
}
import React from 'react'
import { useFormState } from '@agiliza/utils/hooks/state'
import { ActionType } from '@agiliza/utils/hooks/state'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { connected, ConnectedProps } from './connect'
import Form from './Form'
import { initialState } from './state'
import { CDHomeState } from './state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
type ExtendedProps = WithStyles<typeof styles> & ConnectedProps
interface Props extends ExtendedProps {}
interface Props extends ExtendedProps {
state: CDHomeState
actions: ActionType<CDHomeState>
}
const Home = (props: Props) => {
const { classes } = props
const formState = useFormState('homeForm', initialState)
const { classes, context, addressContext, state, actions } = props
return (
<div className={classes.contentContainer}>
<div className={classes.content}>
<Form {...formState} />
<Form state={state} actions={actions} addressContext={addressContext} context={context} />
</div>
</div>
)
}
export default withStyles(styles)(Home)
export default connected(withStyles(styles)(Home))
import { connect } from 'react-redux'
import { AuthenticationContext, ProposalDataContext } from '@agiliza/api/domain'
import { StoreState } from '@agiliza/redux'
import * as entAuthentication from '@agiliza/redux/entities/authentication'
import * as entProposalDataContext from '@agiliza/redux/entities/proposalData/context'
import * as ucProposalDataContext from '@agiliza/redux/useCases/proposalData/context'
export interface ConnectedProps {
fetching: boolean
context: ProposalDataContext
addressContext: AuthenticationContext
}
type StateProps = Pick<ConnectedProps, 'fetching' | 'context' | 'addressContext'>
// type DispatchProps = Pick<ConnectedProps, 'addIndentification'>
const mapStateToProps = (state: StoreState): StateProps => ({
fetching: ucProposalDataContext.selectors.isFetching(state.ui.login),
context: entProposalDataContext.selectors.getContext(state.entities.proposalData.context),
addressContext: entAuthentication.selectors.getContextEntities(state.entities.authentication),
})
// const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
// bindActionCreators(
// {
// },
// dispatch
// )
export const connected = connect(mapStateToProps)
export { default } from './Home'
export * from './Home'
export * from './state'
import { file } from '@agiliza/__mocks__/files'
import { Home } from '@agiliza/api/domain'
type ExtendedState = Home
export interface CustomerHomeState extends ExtendedState {
export interface CDHomeState extends ExtendedState {
hasProperty: boolean
}
export const initialState: CustomerHomeState = {
export const initialState: CDHomeState =
process.env.NODE_ENV === 'development'
? {
hasProperty: false,
address: {
id: '',
cep: '29100100',
city: '16',
complement: 'TEST',
district: 'TEST',
number: '123',
state: '1',
street: 'TEST',
},
proof: file,
cityResideTime: '12',
deed: file,
deedRecord: '1',
hasOnus: false,
marketValue: '1234',
reside: false,
resideTime: '10',
type: '1',
}
: {
hasProperty: true,
address: { id: '', cep: '', city: '', complement: '', district: '', number: '', state: '', street: '', proof: '' },
address: { id: '', cep: '', city: '', complement: '', district: '', number: '', state: '', street: '' },
proof: '',
cityResideTime: '',
deed: '',
deedRecord: '',
......@@ -17,4 +42,4 @@ export const initialState: CustomerHomeState = {
reside: false,
resideTime: '',
type: '',
}
}
......@@ -7,7 +7,19 @@ export interface CDIdentificationState extends ExtendedState {
hasAccount: boolean
}
export const initialState: CDIdentificationState = {
export const initialState: CDIdentificationState =
process.env.NODE_ENV === 'development'
? {
id: '',
name: 'TEST',
cpfcnpj: '80.162.745/0001-96',
gender: '1',
type: INVOLVED_PERSON_TYPES['CUSTOMER'],
hasAccount: false,
account: { agencyNumber: '', number: '', cardPicture: '' },
dataType: { doesWithdrawal: false, framework: '1' },
}
: {
id: '',
name: '',
cpfcnpj: '',
......@@ -16,4 +28,4 @@ export const initialState: CDIdentificationState = {
hasAccount: false,
account: { agencyNumber: '', number: '', cardPicture: '' },
dataType: { doesWithdrawal: false, framework: '' },
}
}
import { file } from '@agiliza/__mocks__/files'
import { PersonalData } from '@agiliza/api/domain'
type ExtendedState = PersonalData
export interface CDPersonalDataState extends ExtendedState {}
export const initialState: CDPersonalDataState = {
export const initialState: CDPersonalDataState =
process.env.NODE_ENV === 'development'
? {
rg: { number: '1234', dispatcherAgency: '1233', front: file, back: file },
birthday: new Date('1985-10-10'),
userCRAS: false,
mothersName: 'TEST',
fathersName: 'TEST',
occupation: 'TEST',
schooling: '1',
maritalStatus: '1',
dependents: '0',
primaryEmail: 'test@email.com',
secundaryEmail: 'test@email.com',
mobile: '27998787541',
landline: '2733414145',
}
: {
rg: { number: '', dispatcherAgency: '', front: '', back: '' },
birthday: null,
userCRAS: false,
......@@ -18,4 +36,4 @@ export const initialState: CDPersonalDataState = {
secundaryEmail: '',
mobile: '',
landline: '',
}
}
import React, { useEffect } from 'react'
import { Reference } from '@agiliza/api/domain'
import { useFormState } from '@agiliza/utils/hooks/state'
import { ProposalDataContext, Reference } from '@agiliza/api/domain'
import { ActionType } from '@agiliza/utils/hooks/state'
import {
Button,
Dialog as MUIDialog,
......@@ -13,23 +13,22 @@ import {
import { withStyles, WithStyles } from '@material-ui/core/styles'
import Form from '../Form'
import { initialState } from '../state'
import { CDReferenceState, initialState } from '../state'
import styles from './styles'
type ExtendedProps = Pick<DialogProps, 'open'> & WithStyles<typeof styles>
interface Props extends ExtendedProps {
state: CDReferenceState
actions: ActionType<CDReferenceState>
onClose: () => void
reference?: Reference
onSave(rfc: Reference): () => void
onSave(rfc: Reference, add: boolean): () => void
context: ProposalDataContext
}
const Dialog = (props: Props) => {
const { classes, open, onClose, onSave, reference } = props
const formState = useFormState('referenceForm', initialState)
const { actions } = formState
const { classes, open, onClose, onSave, reference, context, state, actions } = props
useEffect(() => {
if (reference) actions.update(reference)
......@@ -37,18 +36,18 @@ const Dialog = (props: Props) => {
}, [reference])
const mapStateToReference = (): Reference => {
return formState.state
return state
}
return (
<MUIDialog onClose={onClose} aria-labelledby="simple-dialog-title" open={open} PaperProps={{ className: classes.dialog }}>
<DialogTitle>{reference ? 'Editar' : 'Adicionar'} pessoa envolvida</DialogTitle>
<DialogContent>
<Form {...formState} />
<Form state={state} actions={actions} context={context} />
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancelar</Button>
<Button onClick={onSave(mapStateToReference())}>Salvar</Button>
<Button onClick={onSave(mapStateToReference(), !reference)}>Salvar</Button>
</DialogActions>
</MUIDialog>
)
......
......@@ -7,6 +7,6 @@ import sharedStyles from '../styles'
export default (theme: Theme) => {
return createStyles({
...sharedStyles(theme),
dialog: { height: '40%', width: '40%' },
dialog: { width: '80%', height: '55%' },
})
}
import React from 'react'
import { ProposalDataContext } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import { ActionType } from '@agiliza/utils/hooks/state'
import { maskPhone } from '@agiliza/utils/masks'
import { getBase64FromFile } from '@agiliza/utils/method'
import { SelectField, SelectFieldProps } from '@curio/components'
import { TextField, TextFieldProps } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CustomerReferenceState } from '../state'
import { CDReferenceState } from '../state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
interface Props extends ExtendedProps {
state: CustomerReferenceState
actions: ActionType<CustomerReferenceState>
state: CDReferenceState
actions: ActionType<CDReferenceState>
context: ProposalDataContext
}
const Form = (props: Props) => {
const { classes, state, actions } = props
const { classes, state, actions, context } = props
const { name, telephone } = state
const { name, telephone, photo, type, extraInfo, concept } = state
const handleChangeText =
(key: keyof CustomerReferenceState): TextFieldProps['onChange'] =>
(key: keyof CDReferenceState): TextFieldProps['onChange'] =>
(evt) => {
actions.update({ [key]: evt.target.value })
}
const handleChangePhoto: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await getBase64FromFile(file)
actions.update({ photo: b64 })
}
}
const handleChangeSelect =
(key: keyof Pick<CDReferenceState, 'photo'>): SelectFieldProps['onChange'] =>
(value) => {
actions.update({ [key]: value })
}
return (
<form className={classes.form}>
<ImageUpload label="Foto da referência" image={photo} onChangeImage={handleChangePhoto} className={classes.imageUpload} />
<SelectField
id="type-select"
variant="outlined"
label="Tipo"
value={type}
onChange={handleChangeSelect('photo')}
items={context.referenceTypes.map((st) => ({ label: st.description, value: st.id }))}
shrink={false}
// className={classes.selectField}
/>
<TextField variant="outlined" label="Nome" value={name} onChange={handleChangeText('name')} />
<TextField
variant="outlined"
......@@ -36,6 +66,8 @@ const Form = (props: Props) => {
onChange={handleChangeText('telephone')}
inputProps={{ maxLength: 15 }}
/>
<TextField variant="outlined" label="Outras informações" value={extraInfo} onChange={handleChangeText('extraInfo')} />
<TextField variant="outlined" label="Conceito" value={concept} onChange={handleChangeText('concept')} />
</form>
)
}
......
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { references } from '@agiliza/__mocks__/proposalData'
import { Reference } from '@agiliza/api/domain/proposalData/involvedPeople/reference'
import { ActionType } from '@agiliza/utils/hooks/state'
import { Avatar, List, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { Add as AddIcon, EmojiEmotions as EmojiEmotionsIcon } from '@material-ui/icons'
import { connected, ConnectedProps } from './connect'
import Dialog from './Dialog'
import { CDReferenceState } from './state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
type ExtendedProps = WithStyles<typeof styles> & ConnectedProps
interface Props extends ExtendedProps {}
interface Props extends ExtendedProps {
state: CDReferenceState
actions: ActionType<CDReferenceState>
projectId: string
personId: string
}
const References = (props: Props) => {
const { classes } = props
const { classes, context, state, actions, references, projectId, personId } = props
const [selectedReference, setSelectedReference] = useState<Reference | undefined>()
const [open, setOpen] = useState(false)
useEffect(() => {
props.getReferences({ personId, projectId })
}, [])
const handleClickListItem = (reference: Reference) => () => {
setSelectedReference(reference)
setOpen(true)
......@@ -30,7 +41,23 @@ const References = (props: Props) => {
setSelectedReference(undefined)
}
const handleSave = (reference: Reference) => () => {}
const handleSave = (reference: Reference, add: boolean) => () => {
if (add)
props.addReference({
projectId,
personId,
reference,
onSuccess: () => setOpen(false),
})
else
props.updateReference({
projectId,
personId,
referenceId: reference.id,
reference,
onSuccess: () => setOpen(false),
})
}
return (
<>
......@@ -53,9 +80,17 @@ const References = (props: Props) => {
<Avatar className={classes.avatarBtnContainer} onClick={handleClickAdd}>
<AddIcon />
</Avatar>
<Dialog open={open} onClose={() => setOpen(false)} reference={selectedReference} onSave={handleSave} />
<Dialog
open={open}
onClose={() => setOpen(false)}
reference={selectedReference}
onSave={handleSave}
context={context}
state={state}
actions={actions}
/>
</>
)
}
export default withStyles(styles)(References)
export default connected(withStyles(styles)(References))
import { connect } from 'react-redux'
import { bindActionCreators, Dispatch } from 'redux'
import { ProposalDataContext, Reference } from '@agiliza/api/domain'
import { StoreState } from '@agiliza/redux'
import * as entProposalDataContext from '@agiliza/redux/entities/proposalData/context'
import * as entProposalData from '@agiliza/redux/entities/proposalData/proposal'
import * as ucProposalDataContext from '@agiliza/redux/useCases/proposalData/context'
import * as ucProposalData from '@agiliza/redux/useCases/proposalData/customerData'
export interface ConnectedProps {
fetching: boolean
references: Reference[]
getReferences: typeof ucProposalData.actions.getReferences
addReference: typeof ucProposalData.actions.addReference
updateReference: typeof ucProposalData.actions.updateReference
context: ProposalDataContext
}
type StateProps = Pick<ConnectedProps, 'fetching' | 'context' | 'references'>
type DispatchProps = Pick<ConnectedProps, 'getReferences' | 'addReference' | 'updateReference'>
const mapStateToProps = (state: StoreState): StateProps => ({
fetching: ucProposalDataContext.selectors.isFetching(state.ui.login),
context: entProposalDataContext.selectors.getContext(state.entities.proposalData.context),
references: entProposalData.selectors.getReferences(state.entities.proposalData.proposal),
})
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
bindActionCreators(
{
getReferences: ucProposalData.actions.getReferences,
addReference: ucProposalData.actions.addReference,
updateReference: ucProposalData.actions.updateReference,
},
dispatch
)
export const connected = connect(mapStateToProps, mapDispatchToProps)
export { default } from './References'
export * from './References'
export * from './state'
import { file } from '@agiliza/__mocks__/files'
import { Reference } from '@agiliza/api/domain'
type ExtendedState = Reference
export interface CustomerReferenceState extends ExtendedState {}
export interface CDReferenceState extends ExtendedState {}
export const initialState: CustomerReferenceState = {
export const initialState: CDReferenceState =
process.env.NODE_ENV === 'development'
? { id: '', concept: 'TEST', extraInfo: 'TEST', name: 'TEST', photo: file, telephone: '27998787541', type: '1' }
: {
id: '',
concept: '',
extraInfo: '',
......@@ -12,4 +16,4 @@ export const initialState: CustomerReferenceState = {
photo: '',
telephone: '',
type: '',
}
}
......@@ -6,6 +6,7 @@ import Address, { AddressState } from '@agiliza/components/templates/Address'
import { formatCurrency } from '@agiliza/utils/formatters'
import { ActionType } from '@agiliza/utils/hooks/state'
import { maskCPFCNPJ, maskPhone } from '@agiliza/utils/masks'
import { getBase64FromFile } from '@agiliza/utils/method'
import { DatePicker } from '@curio/components'
import { TextField, TextFieldProps } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
......@@ -39,12 +40,7 @@ const Form = (props: Props) => {
const handleChangeProof: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
})
const b64: string = await getBase64FromFile(file)
actions.update({ proofAddress: b64 })
}
}
......@@ -56,7 +52,7 @@ const Form = (props: Props) => {
return (
<form className={classes.form}>
<TextField variant="outlined" label="Razão social" value={companyName} onChange={handleChangeText('companyName')} />
<TextField variant="outlined" label="CNPJ" value={maskCPFCNPJ(cnpj)} onChange={handleChangeText('cnpj')} />
<TextField variant="outlined" label="CNPJ" value={maskCPFCNPJ(cnpj)} onChange={handleChangeText('cnpj')} inputProps={{ maxLength: 18 }} />
<DatePicker
id="admission-date"
label="Data de admissão"
......
import { file } from '@agiliza/__mocks__/files'
import { SourceIncome } from '@agiliza/api/domain'
type ExtendedState = SourceIncome
export interface CustomerSourceIncomeState extends ExtendedState {}
export const initialState: CustomerSourceIncomeState = {
export const initialState: CustomerSourceIncomeState =
process.env.NODE_ENV === 'development'
? {
cnpj: '78.673.133/0001-16',
address: { cep: '29101100', city: '16', complement: 'TEST', district: 'TEST', number: '1234', state: '1', street: 'TEST', proof: file },
admissionDate: new Date('2000-10-10'),
companyName: 'TEST',
mobile: '27998787411',
position: 'TEST',
netIncome: '2500',
proofAddress: file,
}
: {
cnpj: '',
address: { cep: '', city: '', complement: '', district: '', number: '', state: '', street: '', proof: '' },
admissionDate: null,
......@@ -13,4 +26,4 @@ export const initialState: CustomerSourceIncomeState = {
position: '',
netIncome: '',
proofAddress: '',
}
}
import React from 'react'
import { Workplace } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import { formatCurrency } from '@agiliza/utils/formatters'
import { ActionType } from '@agiliza/utils/hooks/state'
import { maskPhone } from '@agiliza/utils/masks'
import { TextField, TextFieldProps } from '@material-ui/core'
import { maskCPFCNPJ, maskLandline, maskPhone } from '@agiliza/utils/masks'
import { getBase64FromFile } from '@agiliza/utils/method'
import { DatePicker } from '@curio/components'
import { TextField, TextFieldProps, Typography } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CustomerSpousePersonalDataState } from '../state'
import { CDSpousePersonalDataState } from '../../SpouseData/state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
interface Props extends ExtendedProps {
state: CustomerSpousePersonalDataState
actions: ActionType<CustomerSpousePersonalDataState>
state: CDSpousePersonalDataState
actions: ActionType<CDSpousePersonalDataState>
}
const Form = (props: Props) => {
const { classes, state, actions } = props
const { mobile, primaryEmail } = state
const { mobile, landline, primaryEmail, secundaryEmail, workplace } = state
const handleChangeText =
(key: keyof CustomerSpousePersonalDataState): TextFieldProps['onChange'] =>
(key: keyof CDSpousePersonalDataState): TextFieldProps['onChange'] =>
(evt) => {
actions.update({ [key]: evt.target.value })
}
const handleChangePhoto = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await getBase64FromFile(file)
actions.update({ workplace: { proof: b64 } })
}
}
const handleChangeWorkplace =
(key: keyof Workplace): TextFieldProps['onChange'] =>
(evt) => {
actions.update({ workplace: { [key]: evt.target.value } })
}
const handleChangeDate = (key: keyof Pick<Workplace, 'admissionDate'>) => (date: Date | null) => {
actions.update({ workplace: { [key]: date } })
}
return (
<form className={classes.form}>
<TextField variant="outlined" label="Telefone celular" value={maskPhone(mobile)} onChange={handleChangeText('mobile')} />
<TextField variant="outlined" label="Telefone fixo" value={maskLandline(landline)} onChange={handleChangeText('landline')} />
<TextField variant="outlined" label="Email primário" value={primaryEmail} onChange={handleChangeText('primaryEmail')} />
<TextField variant="outlined" label="Email primário" value={secundaryEmail} onChange={handleChangeText('secundaryEmail')} />
<Typography className={classes.workplaceTitle} variant="h6">
Local de trabalho
</Typography>
<TextField variant="outlined" label="Razão social" value={workplace?.workplaceName || ''} onChange={handleChangeWorkplace('workplaceName')} />
<ImageUpload label="Comprovante" image={workplace?.proof || ''} onChangeImage={handleChangePhoto} className={classes.imageUpload} />
<TextField
variant="outlined"
label="CNPJ"
value={maskCPFCNPJ(workplace?.cnpj || '')}
onChange={handleChangeWorkplace('cnpj')}
inputProps={{ maxLength: 18 }}
/>
<DatePicker
id="admission-date"
label="Data de admissão"
value={workplace?.admissionDate}
onChange={handleChangeDate('admissionDate')}
format="dd/MM/yyyy"
className={classes.datePicker}
/>
<TextField variant="outlined" label="Telefone" value={maskPhone(workplace?.phone || '')} onChange={handleChangeWorkplace('phone')} />
<TextField
variant="outlined"
label="Renda líquida"
value={formatCurrency(workplace?.netIncome || '')}
onChange={handleChangeWorkplace('netIncome')}
/>
<TextField variant="outlined" label="Cargo ou função" value={workplace?.role} onChange={handleChangeWorkplace('role')} />
</form>
)
}
......
......@@ -10,5 +10,6 @@ export default (theme: Theme) => {
switchCardPhotoContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly' },
datePicker: { marginBottom: '0px !important' },
workplaceTitle: { marginBottom: theme.spacing(2) },
})
}
import React from 'react'
import { useFormState } from '@agiliza/utils/hooks/state'
import { ActionType } from '@agiliza/utils/hooks/state'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CDSpousePersonalDataState } from '../SpouseData/state'
import Form from './Form'
import { initialState } from './state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
interface Props extends ExtendedProps {}
interface Props extends ExtendedProps {
state: CDSpousePersonalDataState
actions: ActionType<CDSpousePersonalDataState>
}
const SpouseAdditionalData = (props: Props) => {
const { classes } = props
const { classes, state, actions } = props
const formState = useFormState('spouseDataForm', initialState)
return (
<div className={classes.contentContainer}>
<div className={classes.content}>
<Form {...formState} />
<Form state={state} actions={actions} />
</div>
</div>
)
......
import { SpousePersonalData } from '@agiliza/api/domain'
type ExtendedState = SpousePersonalData
export interface CustomerSpousePersonalDataState extends ExtendedState {}
export const initialState: CustomerSpousePersonalDataState = {
landline: '',
mobile: '',
primaryEmail: '',
secundaryEmail: '',
workplace: {
// address: { cep: '', city: '', complement: '', district: '', number: '', state: '', street: '' },
workplaceName: '',
admissionDate: null,
netIncome: '',
phone: '',
proof: '',
role: '',
},
}
......@@ -5,7 +5,7 @@ import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import RGTemplate from '@agiliza/components/templates/RGTemplate'
import { ActionType } from '@agiliza/utils/hooks/state'
import { maskCPFCNPJ } from '@agiliza/utils/masks'
import { extractNumbers } from '@agiliza/utils/method'
import { extractNumbers, getBase64FromFile } from '@agiliza/utils/method'
import { DatePicker, SelectField, SelectFieldProps, Switch } from '@curio/components'
import { TextField, TextFieldProps } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
......@@ -53,12 +53,7 @@ const Form = (props: Props) => {
const handleChangeProof: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
})
const b64: string = await getBase64FromFile(file)
actions.update({ marriageCertificate: b64 })
}
}
......
import { file } from '@agiliza/__mocks__/files'
import { SpousePersonalData } from '@agiliza/api/domain'
type ExtendedState = SpousePersonalData
export interface CDSpousePersonalDataState extends ExtendedState {}
export const initialState: CDSpousePersonalDataState = {
export const initialState: CDSpousePersonalDataState =
process.env.NODE_ENV === 'development'
? {
cpf: '94054291082',
name: 'TEST',
rg: { number: '1234', dispatcherAgency: '123', front: file, back: file },
birthday: new Date('1990-10-10'),
userCRAS: false,
mothersName: 'TEST',
fathersName: 'TEST',
occupation: 'TEST',
schooling: '1',
maritalStatus: '1',
dependents: '0',
participationPercentage: '20',
marriageCertificate: file,
landline: '2733410125',
mobile: '27998787452',
primaryEmail: 'test@email.com',
secundaryEmail: 'test@email.com',
workplace: {
// address: { cep: '', city: '', complement: '', district: '', number: '', state: '', street: '' },
cnpj: '59355240000151',
workplaceName: 'TEST',
admissionDate: new Date('2000-10-10'),
netIncome: '2500',
phone: '27998545787',
proof: file,
role: 'TEST',
},
}
: {
cpf: '',
name: '',
rg: { number: '', dispatcherAgency: '', front: '', back: '' },
......@@ -18,4 +50,17 @@ export const initialState: CDSpousePersonalDataState = {
dependents: '',
participationPercentage: '',
marriageCertificate: '',
}
landline: '',
mobile: '',
primaryEmail: '',
secundaryEmail: '',
workplace: {
// address: { cep: '', city: '', complement: '', district: '', number: '', state: '', street: '' },
workplaceName: '',
admissionDate: null,
netIncome: '',
phone: '',
proof: '',
role: '',
},
}
......@@ -21,7 +21,7 @@ type ExtendedProps = Pick<DialogProps, 'open'> & WithStyles<typeof styles>
interface Props extends ExtendedProps {
onClose: () => void
vehicle?: Vehicle
onSave(rfc: Vehicle): () => void
onSave(rfc: Vehicle, add: boolean): () => void
}
const Dialog = (props: Props) => {
......@@ -48,7 +48,7 @@ const Dialog = (props: Props) => {
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancelar</Button>
<Button onClick={onSave(mapStateToVehicle())}>Salvar</Button>
<Button onClick={onSave(mapStateToVehicle(), !vehicle)}>Salvar</Button>
</DialogActions>
</MUIDialog>
)
......
......@@ -7,6 +7,6 @@ import sharedStyles from '../styles'
export default (theme: Theme) => {
return createStyles({
...sharedStyles(theme),
dialog: { height: '40%', width: '40%' },
dialog: { width: '80%', height: '55%' },
})
}
import React from 'react'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import { formatCurrency } from '@agiliza/utils/formatters'
import { ActionType } from '@agiliza/utils/hooks/state'
import { maskLicensePlate } from '@agiliza/utils/masks'
import { TextField, TextFieldProps } from '@material-ui/core'
import { getBase64FromFile } from '@agiliza/utils/method'
import {
Checkbox,
CheckboxProps,
FormControlLabel,
FormGroup,
TextField,
TextFieldProps
} from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { CustomerVehicleState } from '../state'
import { CDVehicleState } from '../state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
interface Props extends ExtendedProps {
state: CustomerVehicleState
actions: ActionType<CustomerVehicleState>
state: CDVehicleState
actions: ActionType<CDVehicleState>
}
const Form = (props: Props) => {
const { classes, state, actions } = props
const { brand, licensePlate } = state
const { document, brand, licensePlate, model, year, marketValue, hasOnus, hasInsurance } = state
const handleChangeText =
(key: keyof CustomerVehicleState): TextFieldProps['onChange'] =>
(key: keyof CDVehicleState): TextFieldProps['onChange'] =>
(evt) => {
actions.update({ [key]: evt.target.value })
}
const handleChangeImage: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
const file = evt.target.files && evt.target.files[0]
if (file) {
const b64: string = await getBase64FromFile(file)
actions.update({ document: b64 })
}
}
const handleChangeCheckbox =
(key: keyof Pick<CDVehicleState, 'hasInsurance' | 'hasOnus'>): CheckboxProps['onChange'] =>
(_, checked) => {
actions.update({ [key]: checked })
}
return (
<form className={classes.form}>
<ImageUpload label="Documento do veículo" image={document} onChangeImage={handleChangeImage} />
<TextField variant="outlined" label="Modelo" value={model} onChange={handleChangeText('model')} />
<TextField variant="outlined" label="Marca" value={brand} onChange={handleChangeText('brand')} />
<TextField
variant="outlined"
......@@ -36,6 +62,15 @@ const Form = (props: Props) => {
onChange={handleChangeText('licensePlate')}
inputProps={{ maxLength: 8 }}
/>
<TextField variant="outlined" label="Ano" value={year} onChange={handleChangeText('year')} />
<TextField variant="outlined" label="Valor de mercado" value={formatCurrency(marketValue)} onChange={handleChangeText('marketValue')} />
<FormGroup row className={classes.formGroup}>
<FormControlLabel label="Possui ônus?" control={<Checkbox name="reside" checked={hasOnus} onChange={handleChangeCheckbox('hasOnus')} />} />
<FormControlLabel
label="Possui seguro?"
control={<Checkbox name="reside" checked={hasInsurance} onChange={handleChangeCheckbox('hasInsurance')} />}
/>
</FormGroup>
</form>
)
}
......
......@@ -7,8 +7,10 @@ import sharedStyles from '../styles'
export default (theme: Theme) => {
return createStyles({
...sharedStyles(theme),
switchCardPhotoContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly' },
datePicker: { marginBottom: '0px !important' },
formGroup: {
marginBottom: theme.spacing(2),
},
})
}
import React, { useState } from 'react'
import { vehicles } from '@agiliza/__mocks__/proposalData'
import { Vehicle } from '@agiliza/api/domain'
import { ActionType } from '@agiliza/utils/hooks/state'
import { Avatar, List, ListItem, ListItemAvatar, ListItemText } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import { Add as AddIcon, DriveEta as DriveEtaIcon } from '@material-ui/icons'
import { connected, ConnectedProps } from './conect'
import Dialog from './Dialog'
import { CDVehicleState } from './state'
import styles from './styles'
type ExtendedProps = WithStyles<typeof styles>
type ExtendedProps = WithStyles<typeof styles> & ConnectedProps
interface Props extends ExtendedProps {}
interface Props extends ExtendedProps {
projectId: string
personId: string
state: CDVehicleState
actions: ActionType<CDVehicleState>
}
const Vehicles = (props: Props) => {
const { classes } = props
const { classes, projectId, personId, vehicles } = props
const [selectedVehicle, setSelectedVehicle] = useState<Vehicle | undefined>()
......@@ -30,7 +37,23 @@ const Vehicles = (props: Props) => {
setSelectedVehicle(undefined)
}
const handleSave = (vehicle: Vehicle) => () => {}
const handleSave = (vehicle: Vehicle, add: boolean) => () => {
if (add)
props.addVehicle({
projectId,
personId,
vehicle,
onSuccess: () => setOpen(false),
})
else
props.updateVehicle({
projectId,
personId,
vehicleId: vehicle.id,
vehicle,
onSuccess: () => setOpen(false),
})
}
return (
<>
......@@ -58,4 +81,4 @@ const Vehicles = (props: Props) => {
)
}
export default withStyles(styles)(Vehicles)
export default connected(withStyles(styles)(Vehicles))
import { connect } from 'react-redux'
import { bindActionCreators, Dispatch } from 'redux'
import { ProposalDataContext, Vehicle } from '@agiliza/api/domain'
import { StoreState } from '@agiliza/redux'
import * as entProposalDataContext from '@agiliza/redux/entities/proposalData/context'
import * as entProposalData from '@agiliza/redux/entities/proposalData/proposal'
import * as ucProposalDataContext from '@agiliza/redux/useCases/proposalData/context'
import * as ucProposalData from '@agiliza/redux/useCases/proposalData/customerData'
export interface ConnectedProps {
fetching: boolean
vehicles: Vehicle[]
getVehicles: typeof ucProposalData.actions.getVehicles
addVehicle: typeof ucProposalData.actions.addVehicle
updateVehicle: typeof ucProposalData.actions.updateVehicle
context: ProposalDataContext
}
type StateProps = Pick<ConnectedProps, 'fetching' | 'context' | 'vehicles'>
type DispatchProps = Pick<ConnectedProps, 'getVehicles' | 'addVehicle' | 'updateVehicle'>
const mapStateToProps = (state: StoreState): StateProps => ({
fetching: ucProposalDataContext.selectors.isFetching(state.ui.login),
context: entProposalDataContext.selectors.getContext(state.entities.proposalData.context),
vehicles: entProposalData.selectors.getVehicles(state.entities.proposalData.proposal),
})
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
bindActionCreators(
{
getVehicles: ucProposalData.actions.getVehicles,
addVehicle: ucProposalData.actions.addVehicle,
updateVehicle: ucProposalData.actions.updateVehicle,
},
dispatch
)
export const connected = connect(mapStateToProps, mapDispatchToProps)
export { default } from './Vehicles'
export * from './Vehicles'
export * from './state'
......@@ -2,9 +2,9 @@ import { Vehicle } from '@agiliza/api/domain'
type ExtendedState = Vehicle
export interface CustomerVehicleState extends ExtendedState {}
export interface CDVehicleState extends ExtendedState {}
export const initialState: CustomerVehicleState = {
export const initialState: CDVehicleState = {
id: '',
brand: '',
document: '',
......
......@@ -7,11 +7,14 @@ import { Button, MobileStepper, Typography } from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'
import {
AccountBox as AccountBoxIcon,
Apartment as ApartmentIcon,
AttachMoney as AttachMoneyIcon,
CheckBox as CheckBoxIcon,
ContactMail as ContactMailIcon,
DriveEta as DriveEtaIcon,
Forum as ForumIcon,
Home as HomeIcon,
InsertDriveFile as InsertDriveFileIcon,
KeyboardArrowLeft as KeyboardArrowLeftIcon,
KeyboardArrowRight as KeyboardArrowRightIcon,
List as ListIcon,
......@@ -19,17 +22,22 @@ import {
ZoomOutMap as ZoomOutMapIcon
} from '@material-ui/icons'
import { businessDataItems } from './BusinessData'
import BDAddress from './BusinessData/Address'
import BDIdentification from './BusinessData/Identification'
import ProductsServices, {
initialState as bdProductServiceInitState
} from './BusinessData/ProductsServices'
import StockSalesCosts from './BusinessData/StockSalesCosts'
import { connected, ConnectedProps } from './connect'
import Address, { initialState as cdAddressInitState } from './CustomerData/Address'
import Home from './CustomerData/Home'
import Home, { initialState as cdHomeInitState } from './CustomerData/Home'
import Identification, { initialState as cdIdentInitState } from './CustomerData/Identification'
import PersonalData, { initialState as cdPersonalDataInitState } from './CustomerData/PersonalData'
import References from './CustomerData/References'
import References, { initialState as cdReferenceInitState } from './CustomerData/References'
import SourceIncome, { initialState as cdSourceIncomeInitState } from './CustomerData/SourceIncome'
import SpouseAdditionalData from './CustomerData/SpouseAdditionalData'
import SpouseData, { initialState as cdSpouseDataInitState } from './CustomerData/SpouseData'
import Vehicles from './CustomerData/Vehicles'
import Vehicles, { initialState as cdVehicleInitState } from './CustomerData/Vehicles'
import styles from './shared-styles'
export const PROPOSAL_DATA_PATHS = {
......@@ -48,7 +56,7 @@ interface Props extends ExtendedProps {}
const ProposalData = (props: Props) => {
const { classes, fetching, proposalId, personId } = props
const [activeStep, setActiveStep] = useState(4)
const [activeStep, setActiveStep] = useState(12)
useEffect(() => {
props.fetchContext()
......@@ -60,6 +68,11 @@ const ProposalData = (props: Props) => {
const cdAddress = useFormState('cdAddressState', cdAddressInitState)
const cdSourceIncome = useFormState('cdAddressState', cdSourceIncomeInitState)
const cdSpouseData = useFormState('cdAddressState', cdSpouseDataInitState)
const cdReference = useFormState('cdSpoudeAddDataState', cdReferenceInitState)
const cdHomeState = useFormState('cdHomeState', cdHomeInitState)
const cdVehicleState = useFormState('cdVehicleState', cdVehicleInitState)
const bdProductServiceState = useFormState('bdProductServiceState', bdProductServiceInitState)
const customerDataItems = useMemo(
() => [
......@@ -72,12 +85,38 @@ const ProposalData = (props: Props) => {
{ label: 'Endereço', icon: <ContactMailIcon />, component: <Address state={cdAddress.state} actions={cdAddress.actions} /> },
{ label: 'Fonte de renda', icon: <LocalAtmIcon />, component: <SourceIncome state={cdSourceIncome.state} actions={cdSourceIncome.actions} /> },
{ label: 'Cônjuge - Ident.', icon: <ForumIcon />, component: <SpouseData state={cdSpouseData.state} actions={cdSpouseData.actions} /> },
{ label: 'Cônjuge +', icon: <ZoomOutMapIcon />, component: <SpouseAdditionalData /> },
{ label: 'Referências', icon: <CheckBoxIcon />, component: <References /> },
{ label: 'Moradia', icon: <HomeIcon />, component: <Home /> },
{ label: 'Veículos', icon: <DriveEtaIcon />, component: <Vehicles /> },
{
label: 'Cônjuge +',
icon: <ZoomOutMapIcon />,
component: <SpouseAdditionalData state={cdSpouseData.state} actions={cdSpouseData.actions} />,
},
{
label: 'Referências',
icon: <CheckBoxIcon />,
component: <References state={cdReference.state} actions={cdReference.actions} projectId={proposalId} personId={personId} />,
},
{ label: 'Moradia', icon: <HomeIcon />, component: <Home state={cdHomeState.state} actions={cdHomeState.actions} /> },
{
label: 'Veículos',
icon: <DriveEtaIcon />,
component: <Vehicles state={cdVehicleState.state} actions={cdVehicleState.actions} projectId={proposalId} personId={personId} />,
},
],
[cdIdentification, cdPersonalData, cdAddress, cdSpouseData]
[cdIdentification, cdPersonalData, cdAddress, cdSpouseData, cdReference, cdHomeState, cdVehicleState]
)
const businessDataItems = useMemo(
() => [
{ label: 'Identificação', icon: <AccountBoxIcon />, component: <BDIdentification /> },
{ label: 'Endereço', icon: <ApartmentIcon />, component: <BDAddress /> },
{ label: 'Estoque, Vendas e Custos', icon: <AttachMoneyIcon />, component: <StockSalesCosts /> },
{
label: 'Produto',
icon: <InsertDriveFileIcon />,
component: <ProductsServices projectId={proposalId} state={bdProductServiceState.state} actions={bdProductServiceState.actions} />,
},
],
[bdProductServiceState]
)
const proposalDataItems = useMemo(() => [...customerDataItems, ...businessDataItems], [customerDataItems, businessDataItems])
......@@ -124,6 +163,20 @@ const ProposalData = (props: Props) => {
onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1),
})
break
case 5:
props.updateSpouseData({
...projectPersonIds,
spouseData: cdSpouseData.state,
onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1),
})
break
case 7:
props.updateHome({
...projectPersonIds,
home: cdHomeState.state,
onSuccess: () => setActiveStep((prevActiveStep) => prevActiveStep + 1),
})
break
default:
setActiveStep((prevActiveStep) => prevActiveStep + 1)
}
......
......@@ -18,12 +18,20 @@ export interface ConnectedProps {
updateAddress: typeof ucProposalDataCD.actions.updateAddress
updateSourceIncome: typeof ucProposalDataCD.actions.updateSourceIncome
updateSpouseData: typeof ucProposalDataCD.actions.updateSpouseData
updateHome: typeof ucProposalDataCD.actions.updateHome
}
type StateProps = Pick<ConnectedProps, 'fetching' | 'proposalId' | 'personId'>
type DispatchProps = Pick<
ConnectedProps,
'addIndentification' | 'fetchContext' | 'updatePersonalData' | 'updateAddress' | 'getContextAddress' | 'updateSourceIncome' | 'updateSpouseData'
| 'addIndentification'
| 'fetchContext'
| 'updatePersonalData'
| 'updateAddress'
| 'getContextAddress'
| 'updateSourceIncome'
| 'updateSpouseData'
| 'updateHome'
>
const mapStateToProps = (state: StoreState): StateProps => ({
......@@ -42,6 +50,7 @@ const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
getContextAddress: ucAuthentication.actions.getContext,
updateSourceIncome: ucProposalDataCD.actions.updateSourceIncome,
updateSpouseData: ucProposalDataCD.actions.updateSpouseData,
updateHome: ucProposalDataCD.actions.updateHome,
},
dispatch
)
......
......@@ -1264,10 +1264,10 @@
prop-types "^15.7.2"
react-is "^16.8.0 || ^17.0.0"
"@microcredito/client@^0.7.13":
version "0.7.13"
resolved "https://nexus.dev.evologica.com.br/repository/npm/@microcredito/client/-/client-0.7.13.tgz#ab47d224d9e5a373df69375afd086d6db7dee77b"
integrity sha1-q0fSJNnlo3PfaTda/Qhtbbfe53s=
"@microcredito/client@^0.7.14":
version "0.7.14"
resolved "https://nexus.dev.evologica.com.br/repository/npm/@microcredito/client/-/client-0.7.14.tgz#066eb548f6ed10bb8a194ae4511c86f2344f45b6"
integrity sha1-Bm61SPbtELuKGUrkURyG8jRPRbY=
"@nodelib/fs.scandir@2.1.4":
version "2.1.4"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment