/**
 * Created by willian batista on 15/12/16.
 */
load('/model/fornecedor/IntegracaoFornecedorFtp.js');
var DemandaDeCompra = function() {
  this.mapper = mapperFactory.createMapperMult(["EstPedEltrAtivaCp", "EstPedEltrAtivaCpEstPedCpRoteiroCp", "EstPedEltrAtivaCpEstPedEltr", "EstPedCpPendEdi", "EstPedCpPendEmail", 
                                                "PgFornIntegracaoArqPendente", "EstProd", "EstPedEltr", "EstProdSuprimentoEntregaLoja", "PrcFilialPendencia"]);
  this.integracaoFornecedor = new IntegracaoFornecedorFtp();
};


DemandaDeCompra.prototype.validarPossivelAtivacao = function(json){
	var pedidos = this.mapper.selectList('EstPedEltrAtivaCp.pedidosVinculadosNaDemandaDeAtivacao', json);
	if(pedidos.size()>0){
		json.put('pedidos', pedidos);
	}else{
		throw {code: 599, message: "O grupo de pedidos selecionado já foram ativados nos roteiros selecionados ou o seu saldo de demanda foram cancelados!"};
	}
};


DemandaDeCompra.prototype.gravarAtivacao = function(json){
	this.mapper.insert('EstPedEltrAtivaCp.incluirEstPedEltrAtivaCp', json);
};


DemandaDeCompra.prototype.gravarVinculoDoRoteiroDaAtivacao = function(json){
	var ativacaoVinculoRoteiro = {
		'cdCtr': json.get('cdCtr'),
		'cdEmp':json.get('cdEmp'),
		'roteiros': json.get('listaDeRoteirosSelecionados')
	};
	this.mapper.insert('EstPedEltrAtivaCpEstPedCpRoteiroCp.incluirRoteiroDaDemanda', ativacaoVinculoRoteiro);
};


DemandaDeCompra.prototype.gravarPedidosViculadosNaAtivacao = function(json){
	this.mapper.insert('EstPedEltrAtivaCpEstPedEltr.incluirPedidosNaAtivacaoDaDemanda', json);
};

DemandaDeCompra.prototype.ativarPedidoDeCompraPorEdi = function(json){
	try{
		this.mapper.insert('EstPedCpPendEdi.inserirPendenciasEdiDosPedidoDeCompra', {'pedidosDeCompra':json.get('pedidosDeCompra')});
	}catch(err){
		this.mapper.update('EstPedCpPendEdi.atualizarPendenciasEdiDosPedidoDeCompra', {'pedidosDeCompra':json.get('pedidosDeCompra'), 'stsEnv':0});
		this.mapper.update('PgFornIntegracaoArqPendente.setArquivoDeEDIParaReenvio', {'pedidosDeCompra':json.get('pedidosDeCompra')});
	}
};

DemandaDeCompra.prototype.ativarPedidoDeCompraPorEmail = function(json){
	try{
		this.mapper.insert('EstPedCpPendEmail.inserirPendenciasDeEmailDosPedidoDeCompra', {'pedidosDeCompra':json.get('pedidosDeCompra'), 'cdInt': json.get('integracao').get('cdInt')});
	}catch(err){
		this.mapper.update('EstPedCpPendEmail.atualizarPendenciasDeEmailDosPedidoDeCompra', {'pedidosDeCompra':json.get('pedidosDeCompra'), 'stsEnv':0, 'cdInt': json.get('integracao').get('cdInt')});
		this.mapper.update('PgFornIntegracaoArqPendente.setArquivoDeEmailParaReenvio', {'pedidosDeCompra':json.get('pedidosDeCompra')});
	}
};

/**
 * @description
 * Metodo que ativa os pedido de compra gerados durante a demanda
 * esses pedidos podem ser enviados por EDI ou EMAIL
 * 
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 * @throws {InvalidArgumentException}
 */
DemandaDeCompra.prototype.ativarDemandaPedidoDeCopra = function(json){
	if(json == null || json.get('integracao') == null || json.get('pedidosDeCompra') == null)
		throw {code: 599, message: "Dados passados ao servidor inválido!"};
	
	try{
		
			if(json.get('integracao').get('tpInt') == 0 && json.get('integracao').get('tpLayout') == 13){
					this.ativarPedidoDeCompraPorEdi(json);
			}else if(json.get('integracao').get('tpInt') == 1 && json.get('integracao').get('tpLayout') == 14){
					this.integracaoFornecedor.put(json.get('integracao'));
					this.ativarPedidoDeCompraPorEmail(json);
			}
			
			this.mapper.commit();
	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};

/**
 * @description
 * Metodo realiza a ativação da demanda de compra passados por parametro
 * nessa ativação deve ser gravado a ativacao da compra assim como
 * seus vinculos com os roteiro solicitados e pedido vinculados
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 * 
 * @throws {InvalidArgumentException}
 * @throws {SQLException}
 */
DemandaDeCompra.prototype.ativarDemandaDeCompra = function(json){
	if(json === null || json.size() === 0 || json.get("listaDeRoteirosSelecionados").size() === 0){
		 throw {code: 599, message: "Dados passados ao servidor inválido!"};
	}
	 	
	try{
		this.validarPossivelAtivacao(json);
		this.gravarAtivacao(json);
		this.gravarVinculoDoRoteiroDaAtivacao(json);
		this.gravarPedidosViculadosNaAtivacao(json);
		this.mapper.commit();
	}catch(err){
		this.mapper.rollback();
		throw err;
	}

};


/**
 * @description
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 */
DemandaDeCompra.prototype.adicionarProdutosAoPedidoEspecial = function(json){

        let param = {
            'cdUsu': json.get('cdUsu'),
            'justificativa': 'ALTERADO POR RATEIO DE PEDIDO ESPECIAL',
            'filiais': []
		};
		
		let flagAgrupadoPorProduto = (json.get('cdDepoEntrega') > 0 ? 1 : 0);
		let flagSomenteProdutoComDemanda =  (json.get('cdDepoEntrega') > 0 ? 1 : 0);

        while(json.get("vlrPedido") < json.get("vlrPedidoEspecial")){
			let produto = this.mapper.selectOne("EstProd.listarProdutosComMenorCoberturaDaDemanda", 
				{'cdUsu': json.get('cdUsu'), 'cdEmp': json.get('cdEmp'), 'flagAgrupadoPorProduto':flagAgrupadoPorProduto, 'flagSomenteProdutoComDemanda':flagSomenteProdutoComDemanda});

            let intQtdeProd = parseFloat(produto.get("qtdeProd")) + 1;

            if(param.filiais.length == 0){
                param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
            }else{
                let flagEncontrado = false;
                for(let i = 0; i<param.filiais.length; i++){
                    if(param.filiais[i].cdFilial == produto.get('cdFilial') && param.filiais[i].cdProd == produto.get('cdProd')){
                        param.filiais[i].quantidade = intQtdeProd;
                        flagEncontrado = true;
                        break;
                    }
                }
                if(!flagEncontrado)
                    param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
            }

            this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': json.get('cdEmp'), 'cdUsu':json.get('cdUsu'), 'cdProd': produto.get('cdProd'), 'cdFilial':produto.get('cdFilial'), 'qtdeProd':intQtdeProd});
            json.put('vlrPedido', parseFloat(json.get('vlrPedido')) + parseFloat(produto.get('vlrProdLiq')));
        }

        this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistoricoEmLote', param);
};


/**
 * @description
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 */
DemandaDeCompra.prototype.abaterProdutosAoPedidoEspecial = function(json){

    let param = {
        'cdUsu': json.get('cdUsu'),
        'justificativa': 'ALTERADO POR RATEIO DE PEDIDO ESPECIAL',
        'filiais': []
	};
	
	let flagAgrupadoPorProduto = (json.get('cdDepoEntrega') > 0 ? 1 : 0);
	let flagSomenteProdutoComDemanda =  (json.get('cdDepoEntrega') > 0 ? 1 : 0);

    while(parseFloat(json.get("vlrPedido")) > parseFloat(json.get("vlrPedidoEspecial"))){
		let produto = this.mapper.selectOne("EstProd.listarProdutosComMenorCoberturaDaDemanda", 
			{'cdUsu': json.get('cdUsu'), 'cdEmp': json.get('cdEmp'), 'inverter':true, 'flagAgrupadoPorProduto':flagAgrupadoPorProduto, 'flagSomenteProdutoComDemanda':flagSomenteProdutoComDemanda});

        let intQtdeProd = parseFloat(produto.get("qtdeProd")) - 1;

        if(param.filiais.length == 0){
            param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
        }else{
            let flagEncontrado = false;
            for(let i = 0; i<param.filiais.length; i++){
                if(param.filiais[i].cdFilial == produto.get('cdFilial') && param.filiais[i].cdProd == produto.get('cdProd')){
                    param.filiais[i].quantidade = intQtdeProd;
                    flagEncontrado = true;
                    break;
                }
            }
            if(!flagEncontrado)
                param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
        }

        this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': json.get('cdEmp'), 'cdUsu':json.get('cdUsu'), 'cdProd': produto.get('cdProd'), 'cdFilial':produto.get('cdFilial'), 'qtdeProd':intQtdeProd});
        json.put('vlrPedido', parseFloat(json.get('vlrPedido')) - parseFloat(produto.get('vlrProdLiq')));
    }

    this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistoricoEmLote', param);
};


/**
 * @description
 * Metodo realiza o rateamento da demanda até o valor definido
 * para o pedido especial, a ordem de precedencias dos produtos
 * é baseado em sua coberturar, para adicionar produtos é considerado
 * a menor cobertura e para remover a maior
 * Cobertura = (qtedEst/mediaF) * 30
 * 
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 * @throws {InvalidArgumentException}
 * @throws {SQLException}
 */
DemandaDeCompra.prototype.ratearPedidoComoEspecial = function(json){
	if(json === null || json.size() === 0 || json.get("vlrPedidoEspecial") == 0){
		 throw {code: 599, message: "Dados passados ao servidor inválido!"};
	}
	
	try{
		if(json.get("vlrPedidoEspecial") > json.get("vlrPedido")){
			this.adicionarProdutosAoPedidoEspecial(json);
			this.mapper.commit();
		}
		else if (json.get("vlrPedidoEspecial") < json.get("vlrPedido")){
			this.abaterProdutosAoPedidoEspecial(json);
			this.mapper.commit();
		}

	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};



/**
 * @description
 * Metodo incrementa a quantidade dos produtos sugeridos para a demanda
 * até que todas as filiais com pedido inferior ao minimo se igualem.
 * 
 * @param cdEmp {Object JS} código da empresa responsavel
 * @param cdUsu {Object JS} usuario responsavel pela demanda
 * @param vlrPedidoMinimo {Object JS} valor minimo para o pedido pro filial
 * @param vlrPedidoFilial {Object JS}  valor total do pedido até o momento para a filial
 * @throws {SQLException}
 */
DemandaDeCompra.prototype.adicionarProdutoAoPedidoMinimo = function(cdEmp, cdUsu, vlrPedidoMinimo, cdFilial, vlrPedidoFilial){

     let param = {
        'cdUsu': cdUsu,
        'justificativa': 'ALTERADO POR RATEIO DE PEDIDO MINIMO',
        'filiais': []
     };

    while(vlrPedidoFilial < vlrPedidoMinimo){
        let produto = this.mapper.selectOne("EstProd.listarProdutosComMenorCoberturaDaDemanda", {'cdEmp': cdEmp, 'cdUsu': cdUsu, 'cdFilial': cdFilial});
        let intQtdeProd = parseFloat(produto.get("qtdeProd")) + 1;

        if(param.filiais.length == 0){
            param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
        }else{
            let flagEncontrado = false;
            for(let i = 0; i<param.filiais.length; i++){
                if(param.filiais[i].cdFilial == produto.get('cdFilial') && param.filiais[i].cdProd == produto.get('cdProd')){
                    param.filiais[i].quantidade = intQtdeProd;
                    flagEncontrado = true;
                    break;
                }
            }
            if(!flagEncontrado)
                param.filiais.push({'cdFilial': produto.get('cdFilial'), 'cdProd': produto.get('cdProd'), 'quantidade': intQtdeProd});
        }

        this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': cdEmp, 'cdUsu':cdUsu, 'cdProd': produto.get('cdProd'), 'cdFilial':produto.get('cdFilial'), 'qtdeProd':intQtdeProd});
        vlrPedidoFilial = vlrPedidoFilial + parseFloat(produto.get('vlrProdLiq'));
    }

    this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistoricoEmLote', param);
};


/**
 * @description
 * Metodo incrementa a quantidade dos produtos sugeridos para a demanda
 * até que todas as filiais atendam ao pedido minimo definido pelo usuario.
 * A compra para uma filial é zerado, quando a filial tem menos de 50% do valor minimo
 * 
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 * @throws {InvalidArgumentException}
 */
DemandaDeCompra.prototype.ratearPedidoMinimo = function(json){
	if(json === null || json.size() === 0 || json.get("vlrPedidoMinimo") == null || json.get("vlrPedidoMinimo") == 0 || json.get("filiais") == null || json.get("filiais").size() == 0)
		 throw {code: 599, message: "Dados passados ao servidor inválido!"};
	
	try{
		
			for(var i=0; i<json.get("filiais").size(); i++){
				let filial = json.get("filiais").get(i);
				if(Math.round(filial.get("vlrTotal")/json.get("vlrPedidoMinimo")) > 0){
					this.adicionarProdutoAoPedidoMinimo(json.get('cdEmp'), json.get('cdUsu'), parseFloat(json.get('vlrPedidoMinimo')), json.get("filiais").get(i).get('cdFilial'), parseFloat(json.get("filiais").get(i).get('vlrTotal')));
				}else{
				    this.mapper.update("EstProdSuprimentoEntregaLoja.atualizarHistorico", {'cdEmp': json.get('cdEmp'), 'cdUsu': json.get('cdUsu'), 'cdFilial': filial.get('cdFilial'), 'quantidade': 0, 'justificativa':'ZERADO POR RATEIO DE PEDIDO MINIMO', 'flagQtdeDiferente': true});
					this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': json.get('cdEmp'), 'cdUsu': json.get('cdUsu'), 'cdFilial': filial.get('cdFilial'), 'qtdeProd': 0});
                }
			}

			this.mapper.commit();

	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};


/**
 * @description
 * Incrementa a quantidade de produto e sugestao do produto,
 * chamada recursiva até atingir o valor da meta
 * 
 * @param valorDaMeta {Integer JAVA} valor limite que deseja alcançar
 * @param valorCorrente {Integer JAVA} valor corrente da quantidade de produto
 * @param cdProd {Integer JAVA} código do produto a ser tabalhado da demanda
 * @param cdEmp {Integer JAVA} código da empresa a ser tabalhado da demanda
 * @param cdUsu {Integer JAVA} código do usuario responsavel pela demanda
 */
DemandaDeCompra.prototype.incrementarRateioItem = function(valorDaMeta, valorCorrente, cdProd, cdEmp, cdUsu, justificativa){
    let param = {
        'cdUsu': cdUsu,
        'cdProd': cdProd,
        'justificativa': justificativa,
        'filiais': []
    };
	while(valorCorrente < valorDaMeta){
		let produto = this.mapper.selectOne("EstProd.listarProdutosComMenorCoberturaDaDemanda", {'cdEmp': cdEmp, 'cdUsu':cdUsu, 'cdProd': cdProd});
		let intQtdeProd =  parseFloat(produto.get("qtdeProd")) + 1;

		if(param.filiais.length == 0){
		    param.filiais.push({'cdFilial': produto.get('cdFilial'), 'quantidade': intQtdeProd});
		}else{
		    let flagEncontrado = false;
		    for(let i =0; i<param.filiais.length; i++){
		        if(param.filiais[i].cdFilial == produto.get('cdFilial')){
		            param.filiais[i].quantidade = intQtdeProd;
		            flagEncontrado = true;
		            break;
		        }
		    }
		    if(!flagEncontrado)
		        param.filiais.push({'cdFilial': produto.get('cdFilial'), 'quantidade': intQtdeProd});
		}
		
		this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': cdEmp, 'cdUsu':cdUsu, 'cdProd': cdProd, 'cdFilial':produto.get('cdFilial'), 'qtdeProd':intQtdeProd});
		valorCorrente = parseInt(valorCorrente)+1;
	}

	this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistoricoEmLote', param);
};

/**
 * @description
 * Decrementa a quantidade de produto e sugestao do produto,
 * chamada recursiva até atingir o valor da meta.
 * 
 * @param valorDaMeta {Integer JAVA} valor limite que deseja alcançar
 * @param valorCorrente {Integer JAVA} valor corrente da quantidade de produto
 * @param cdProd {Integer JAVA} código do produto a ser tabalhado da demanda
 * @param cdEmp {Integer JAVA} código da empresa a ser tabalhado da demanda
 * @param cdUsu {Integer JAVA} código do usuario responsavel pela demanda
 */
DemandaDeCompra.prototype.decrementarRateioItem = function(valorDaMeta, valorCorrente, cdProd, cdEmp, cdUsu, justificativa, flagSomenteProdutoComDemanda){
    let param = {
        'cdUsu': cdUsu,
        'cdProd': cdProd,
        'justificativa': justificativa,
        'filiais': []
    };


	while(valorCorrente > valorDaMeta){
		let produto = this.mapper.selectOne("EstProd.listarProdutosComMenorCoberturaDaDemanda", 
			{'cdEmp': cdEmp, 'cdUsu': cdUsu, 'cdProd': cdProd, 'inverter': true, 'flagSomenteProdutoComDemanda':flagSomenteProdutoComDemanda});

		let intQtdeProd =  parseFloat(produto.get("qtdeProd")) - 1;

		if(param.filiais.length == 0){
            param.filiais.push({'cdFilial': produto.get('cdFilial'), 'quantidade': intQtdeProd});
        }else{
            let flagEncontrado = false;
            for(let i =0; i<param.filiais.length; i++){
                if(param.filiais[i].cdFilial == produto.get('cdFilial')){
                    param.filiais[i].quantidade = intQtdeProd;
                    flagEncontrado = true;
                    break;
                }
            }
            if(!flagEncontrado)
                param.filiais.push({'cdFilial': produto.get('cdFilial'), 'quantidade': intQtdeProd});
        }
		
		this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': cdEmp, 'cdUsu':cdUsu, 'cdProd': cdProd, 'cdFilial':produto.get('cdFilial'), 'qtdeProd':intQtdeProd});
		valorCorrente = parseInt(valorCorrente)-1;
	}

	this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistoricoEmLote', param);
};

DemandaDeCompra.prototype.setProdutoZerado = function (cdEmp, cdUsu, cdProd, justificativa){
    let param = {
        'cdEmp': cdEmp,
        'cdUsu': cdUsu,
        'cdProd': cdProd,
        'quantidade': 0,
        'justificativa': justificativa,
        'flagQtdeDiferente': true
    };
    this.mapper.insert('EstProdSuprimentoEntregaLoja.atualizarHistorico', param);
	this.mapper.update("EstProd.atualizarRateioItemDemanda", {'cdEmp': cdEmp, 'cdUsu':cdUsu, 'cdProd': cdProd, 'qtdeProd': 0});
};


/**
 * @description
 * Metodo faz o rateio do novo valor da quantidade de produto nas filiais (direto loja)
 * 
 * @param json {HashMap JAVA} parametro passado no momento da requisicao
 * @throws {InvalidArgumentException}
 */
DemandaDeCompra.prototype.ratearItem = function(json){
	if(json === null || json.size() === 0 || json.get("cdEmp") == null || json.get("cdUsu") == null || json.get("produto") == null)
		 throw {code: 599, message: "Dados passados ao servidor inválido!"};
	
	try{

        let justificativa = 'RATEIO DA QUANTIDADE DE PRODUTOS NAS FILIAIS';
        if(json.get("produto").get("qtdeProd") == 0){
            this.setProdutoZerado(json.get("cdEmp"), json.get("cdUsu"), json.get("produto").get('cdProd'), justificativa);

        }else{

            let produtoAtual = this.mapper.selectOne("EstProdSuprimentoEntregaLoja.listarDemandaAgrupadoPorProduto", {'cdEmp': json.get("cdEmp"), 'cdUsu':json.get("cdUsu"), 'cdProd': json.get("produto").get('cdProd')});

            if(json.get("produto").get("qtdeProd") > 0 && json.get("produto").get("qtdeProd") > Math.round(produtoAtual.get('qtdeProd'), 0))
                this.incrementarRateioItem(json.get("produto").get("qtdeProd"), Math.round(produtoAtual.get('qtdeProd')), json.get("produto").get("cdProd"), json.get("cdEmp"), json.get("cdUsu"), justificativa);
            else if(json.get("produto").get("qtdeProd") > 0 && json.get("produto").get("qtdeProd") < Math.round(produtoAtual.get('qtdeProd'), 0))
                this.decrementarRateioItem(json.get("produto").get("qtdeProd"), Math.round(produtoAtual.get('qtdeProd')), json.get("produto").get("cdProd"), json.get("cdEmp"), json.get("cdUsu"), justificativa, 1);
        }

        this.mapper.commit();

	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};


DemandaDeCompra.prototype.arredondarEmbalagemPorFornecedor = function (json){
	if(json.get('cdDepoEntrega') == 0){
		this.mapper.update('EstProd.realizarArrendondamentoPorFornecedor', json);

	}else{
		let justificativa =  'ARREDONDAMENTO DE EMBALAGEM FORNECEDOR: '+json.get('cdForn');
		let produtos = this.mapper.selectList('EstProd.qtdeProdArredondadoPorFornecedor', {'cdUsu': json.get('cdUsu'), 'cdEmp': json.get('cdEmp'), 'cdForn': json.get('cdForn')});

		for(i = 0; i<produtos.size(); i++){
			let produto = produtos.get(i);
			let qtdeArredondada = produto.get('qtdeProdArredondado');

			if(qtdeArredondada != Math.round(produto.get('qtdeProd'), 0)){
			
                if(qtdeArredondada <= 0 && json.get('forcarCaixaFechada') == 0)
                    this.setProdutoZerado(json.get('cdEmp'), json.get('cdUsu'), produto.get('cdProd'), justificativa);

                else if(qtdeArredondada <= 0 && json.get('forcarCaixaFechada') == 1 && Math.round(produto.get('qtdeProd'), 0) > 0)
                    this.incrementarRateioItem(produto.get('qtEmbCompra'), Math.round(produto.get('qtdeProd'), 0), produto.get('cdProd'), json.get('cdEmp'), json.get('cdUsu'), justificativa);

                else if(qtdeArredondada <= 0 && message.get('forcarCaixaFechada') == 1 && Math.round(produto.get('qtdeProd'), 0) <= 0)
                    this.setProdutoZerado(message.get('cdEmp'), message.get('cdUsu'), produto.get('cdProd'), justificativa);

                else if(qtdeArredondada > Math.round(produto.get('qtdeProd'), 0))
                    this.incrementarRateioItem(qtdeArredondada, Math.round(produto.get('qtdeProd'), 0), produto.get('cdProd'), json.get('cdEmp'), json.get('cdUsu'), justificativa);

                else if (qtdeArredondada < Math.round(produto.get('qtdeProd'), 0))
                    this.decrementarRateioItem(qtdeArredondada, Math.round(produto.get('qtdeProd'), 0), produto.get('cdProd'), json.get('cdEmp'), json.get('cdUsu'), justificativa);
            }
		}
	}
};


DemandaDeCompra.prototype.podutoJaInserido = function(produto, lista){
	for(let j in lista){
		if(lista[j].get('cdProd') == produto.get('cdProd')){
			lista[j].put('qtdeProd', parseFloat(lista[j].get('qtdeProd')) + parseFloat(produto.get('qtdeProd')));
			return true;
		}
	}
	
	return false;
};


DemandaDeCompra.prototype.unificarDemanda = function (json){
	let produtos = this.mapper.selectList('EstProdSuprimentoEntregaLoja.listarEstProdSuprimentoEntregaLoja', {'cdEmp':json.get('cdEmp') , 'cdUsu':json.get('cdUsu')});
	let novosProdutosDemanda = [];
	
	for(let i = 0; i<produtos.size(); i++){
		let produto = produtos.get(i);
		if(!this.podutoJaInserido(produto, novosProdutosDemanda)){
			produto.put('cdFilial', json.get('cdFilialUnificada'));
			novosProdutosDemanda.push(produto);
		}
	}
	
	this.mapper.update('EstProdSuprimentoEntregaLoja.excluirEstProdSuprimentoEntregaLoja', json);

	let param = [];
	let numMarkers = 0;
	for(let c = 0; c<novosProdutosDemanda.length; c++){
		let item = novosProdutosDemanda[c];

		if((numMarkers + 29) > 2000){
			this.mapper.insert('EstProdSuprimentoEntregaLoja.incluirEstProdSuprimentoEntregaLojaEmMassa', {'produtos': param});
			param = [];
			numMarkers = 0;
            c --;
		}else{
			param.push(item);
			numMarkers = numMarkers + 29;
		}
	}

	if(param.length > 0)
        this.mapper.insert('EstProdSuprimentoEntregaLoja.incluirEstProdSuprimentoEntregaLojaEmMassa', {'produtos': param});

};


DemandaDeCompra.prototype.salvarDemanda = function (json){
	try{
		
		if(json.get('pedidoCompraForn') && json.get('cdForn') && json.get('naoConverteEmbPedidoCompra') == 0)//Demanda gerando pedido de compra com conversão de embalagem
			this.arredondarEmbalagemPorFornecedor(json);
		
		if(json.get('cdFilialUnificada') != null)
			this.unificarDemanda(json);
		
		var result = this.mapper.selectList('EstPedEltr.incluirEstPedEltr', json);
		this.mapper.commit();
		return result;
		
	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};

/**
* @description
* Se o atributo {cdProd} for passado dentro do argumento {json}
* a atualização da quantidade e valor é aplicada especificamente para esse produto,
* caso não toda a lista é verificada para atualização.
**/
DemandaDeCompra.prototype.atualizarQtdeDemanda = function (json){
	try{
		
		if(json.get('integrado')){//INTEGRADO

			if(json.get('modo') == 0){
				this.mapper.update('EstProdSuprimentoEntregaLoja.setQuantidadeOriginal', {'cdEmp':json.get('cdEmp') ,'cdUsu':json.get('cdUsu')});
				
			}else if(json.get('modo') == 1){
				this.mapper.update('EstProdSuprimentoEntregaLoja.setSugestao', {'cdEmp':json.get('cdEmp') ,'cdUsu':json.get('cdUsu')});
				
			}else if(json.get('modo') == 2){
				this.mapper.update('EstProdSuprimentoEntregaLoja.setIntegrado', {'cdEmp':json.get('cdEmp') ,'cdUsu':json.get('cdUsu')});
				
			}else{
			    let justificativa = 'ALTERADO PELO USUARIO';
				let produtos = this.mapper.selectList('EstProdSuprimentoEntregaLoja.listarDemandaAgrupadoPorProduto', {'cdEmp':json.get('cdEmp') ,'cdUsu':json.get('cdUsu'), 'cdProd':json.get('cdProd')});
	
				for(i = 0; i<produtos.size(); i++){
					let produto = produtos.get(i);
					
					for(j = 0; j<json.get('itens').size(); j++){
						let item = json.get('itens').get(j);
						
						if(item.get('cdProd') == produto.get('cdProd')){
							if(item.get('qtdeProd') == 0 && item.get('qtdeProd') != Math.round(produto.get('qtdeProd'),0)){
								this.setProdutoZerado(json.get('cdEmp'), json.get('cdUsu'), item.get('cdProd'), justificativa);

							}else if(item.get('qtdeProd') > 0 && item.get('qtdeProd') > Math.round(produto.get('qtdeProd'),0)){
								this.incrementarRateioItem(item.get('qtdeProd'), Math.round(produto.get('qtdeProd'),0), item.get('cdProd'), json.get('cdEmp'), json.get('cdUsu'), justificativa);

							}else if(item.get('qtdeProd') > 0 && item.get('qtdeProd') < Math.round(produto.get('qtdeProd'),0)){
								this.decrementarRateioItem(item.get('qtdeProd'), Math.round(produto.get('qtdeProd'),0), item.get('cdProd'), json.get('cdEmp'), json.get('cdUsu'), justificativa);
							}

							if((item.get('vlrProd') >= 0 && item.get('vlrProd') != produto.get('vlrProd')) || (item.get('percDesc') >= 0 && item.get('percDesc') != produto.get('percDesc')))
							    this.mapper.update('EstProd.atualizarRateioItemDemanda', {'cdEmp':json.get('cdEmp'), 'cdUsu':json.get('cdUsu'), 'cdProd':item.get('cdProd'), 'vlrProd': item.get('vlrProd'), 'percDesc': item.get('percDesc')});

							json.get('itens').remove(j);
							break;
						}
					}
				}
			}
			
		}else{//DIRETO LOJA

		    if(json.get('acao') == 'alterarPrecoDesc'){
                this.mapper.update('EstProd.atualizarRateioItemDemanda', json);

		    }else{
                let param = {
                    'itens': [],
                    'cdUsu': json.get('cdUsu')
                };
                let numMarkers = 0;

                for(let i = 0; i < json.get('itens').size(); i++){
                    let item = json.get('itens').get(i);
                    if((numMarkers + 11) > 2000){

                        this.mapper.update('EstProd.atualizarQtdeDemanda', param);
                        param.itens = [];
                        numMarkers = 0;
                        i --;
                    }else{
                        param.itens.push(item);
                        numMarkers = numMarkers + 11;
                    }
                }

                if(param.itens.length > 0)
                    this.mapper.update('EstProd.atualizarQtdeDemanda', param);
            }
		}
		
		this.mapper.commit();
	
	}catch(err){
	    println(err);
		this.mapper.rollback();
		throw err;
	}
};


DemandaDeCompra.prototype.gerarDemanda = function (dados){
	try{

        let response = {
            'sucesso': false,
            'pendencias': []
        };

        response.pendencias = this.mapper.selectList('PrcFilialPendencia.getPendenciasPorFiliais', dados);

        if(response.pendencias.size() == 0){
            this.mapper.update('EstProd.geraDemandaAgenda', dados);
            this.mapper.insert('EstProdSuprimentoEntregaLoja.auditoriaInicial', {'cdEmp': dados.get('cdEmp'), 'cdUsu': dados.get('cdUsu')});
            this.mapper.commit();
            response.sucesso = true;
         }

		return response;

	}catch(err){
		this.mapper.rollback();
		throw err;
	}
};


DemandaDeCompra.prototype.adicionarNovosProduto = function (dados){

	if(dados == null || dados.get('cdEmp') == null || dados.get('cdUsu') == null || dados.get('produtosAlterados') == null || dados.get('produtosInseridos') == null)
		throw {code: 599, message: "Dados passados ao servidor inválido!"};

	try{
		let dadosComplementares = this.mapper.selectOne('EstProdSuprimentoEntregaLoja.listarDadosComplementares', {'cdEmp': dados.get('cdEmp'), 'cdUsu': dados.get('cdUsu')});
	
		let service = java.util.concurrent.Executors.newFixedThreadPool(2);
		let futureList = new java.util.ArrayList();
		let callableInsert = new java.util.concurrent.Callable(
			{'dadosComplementares': dadosComplementares,
			'obj': this,
			'call': function(){
				this.obj.inserirNovoProdutos(dados, dadosComplementares);
			}
		});

		let callableUpdate = new java.util.concurrent.Callable(
			{'obj': this,
			'call': function(){
				this.obj.alterarProdutos(dados);
			}
		});

		futureList.add(callableInsert);
		futureList.add(callableUpdate);
	
		service.invokeAll(futureList);
		service.shutdown();
	
		this.mapper.commit();
	
	}catch(err){
		this.mapper.rollback();
		println(err);
		throw err;
	}
};

DemandaDeCompra.prototype.inserirNovoProdutos = function(dados, dadosComplementares){
    if(dados.get('produtosInseridos').size() == 0)
        return;

    let param = {
        'produtos': [],
        'cdEmp': dados.get('cdEmp'),
        'cdUsu': dados.get('cdUsu'),
        'isEncomenda':  dados.get('isEncomenda'),
        'listaPreco': dadosComplementares.get('listaPreco'),
        'consideraEstCd':  dadosComplementares.get('consideraEstCd'),
        'cdAgenda':  dadosComplementares.get('cdAgenda'),
        'cdDepoEntrega':  dadosComplementares.get('cdDepoEntrega'),
        'paramEstAA' :  dadosComplementares.get('paramEstAA'),
        'paramEstA':  dadosComplementares.get('paramEstA'),
        'paramEstB':  dadosComplementares.get('paramEstB'),
        'paramEstC':  dadosComplementares.get('paramEstC'),
        'paramEstD':  dadosComplementares.get('paramEstD'),
        'cdSiglaCurva':  dadosComplementares.get('cdSiglaCurva'),
        'tipoCompra':  dadosComplementares.get('tipoCompra'),
        'tpReq':  dadosComplementares.get('tpReq'),
        'leadTime':  dadosComplementares.get('leadTime'),
        'dtProxAgenda':  dadosComplementares.get('dtProxAgenda'),
        'acresDiasProxAgenda':  dadosComplementares.get('acresDiasProxAgenda'),
        'consideraFace':  dadosComplementares.get('consideraFace'),
        'naoUtilizaAgdFace':  dadosComplementares.get('naoUtilizaAgdFace'),
        'listaFiliais':  dadosComplementares.get('listaFiliais'),
        'listaProduto':  dadosComplementares.get('listaProduto'),
        'listaDeposito':  dadosComplementares.get('listaDeposito'),
        'ignorarExcessoDemandaIntegrada':  dadosComplementares.get('ignorarExcessoDemandaIntegrada')
    };

    let numMarkers = 0;

    for(let i = 0; i < dados.get('produtosInseridos').size(); i++){
        let item = dados.get('produtosInseridos').get(i);
        if((numMarkers + 6) > 2000){

            this.mapper.insert('EstProdSuprimentoEntregaLoja.incluirProdutosEmLote', param);
            param.produtos = [];
            numMarkers = 0;
            i --;
        }else{
            param.produtos.push(item);
            numMarkers = numMarkers + 6;
        }
    }

    if(param.produtos.length > 0)
		this.mapper.insert('EstProdSuprimentoEntregaLoja.incluirProdutosEmLote', param);
     
};

DemandaDeCompra.prototype.alterarProdutos = function(dados){
    if(dados.get('produtosAlterados').size() == 0)
        return;

    let param = {
        'produtos': [],
        'cdEmp': dados.get('cdEmp'),
        'cdUsu': dados.get('cdUsu'),
        'isEncomenda': dados.get('isEncomenda')
    };
    let numMarkers = 0;

    for(let i = 0; i < dados.get('produtosAlterados').size(); i++){
        let item = dados.get('produtosAlterados').get(i);
        if((numMarkers + 6) > 2000){

            this.mapper.update('EstProdSuprimentoEntregaLoja.alterarQuantidadeDeProdutoEmLote', param);
            param.produtos = [];
            numMarkers = 0;
            i --;
        }else{
            param.produtos.push(item);
            numMarkers = numMarkers + 6;
        }
    }

    if(param.produtos.length > 0)
		this.mapper.update('EstProdSuprimentoEntregaLoja.alterarQuantidadeDeProdutoEmLote', param);

};