public static function save()
 {
     $osTO = new OrdemServicoTO();
     $osTO->__setAll($_POST);
     $validator = new DataValidator();
     $validator->set_msg('O campo Cliente é obrigatório')->set('id_cliente', $osTO->cliente)->is_required();
     if (!$validator->validate()) {
         Flight::response()->status(406)->header('Content-Type', 'application/json')->write(json_encode($validator->get_errors()))->send();
         return;
     }
     $cliTO = new UsuarioTO();
     $cliTO->__setAll($osTO->cliente);
     $osTO->cliente = $cliTO;
     $crtTO = new UsuarioTO();
     $crtTO->__setAll($osTO->criador);
     $osTO->criador = $crtTO;
     if (count($osTO->servicos) > 0) {
         foreach ($osTO->servicos as $key => $servico) {
             $newObjTO = new ServicoTO();
             $newObjTO->__setAll($servico);
             $osTO->servicos[$key] = $newObjTO;
         }
     }
     if (count($osTO->produtos) > 0) {
         foreach ($osTO->produtos as $key => $produto) {
             $newObjTO = new ProdutoOSTO();
             $newObjTO->__setAll($produto);
             $osTO->produtos[$key] = $newObjTO;
         }
     }
     if (!$osTO->id) {
         // Grava a venda
         $venTO = new VendaTO();
         $venTO->id_usuario = $osTO->criador->id;
         $venTO->id_cliente = $osTO->cliente->id;
         $venTO->venda_confirmada = $osTO->cod_status_servico == "4" ? 0 : 1;
         $venTO->id_empreendimento = $osTO->id_empreendimento;
         $venTO->id_status_venda = $osTO->cod_status_servico == "4" ? 5 : 6;
         $venDao = new VendaDao();
         $venTO->id = $venDao->saveVenda($venTO);
         if (!$venTO->id) {
             Flight::halt(500, 'Erro ao salvar as informações da venda');
         } else {
             $osTO->id_venda = $venTO->id;
             // Grava os servicos na venda
             if (count($osTO->servicos) > 0) {
                 foreach ($osTO->servicos as $key => $servico) {
                     $itvTO = new ItemVendaTO();
                     $itvTO->id_venda = $venTO->id;
                     $itvTO->id_produto = NULL;
                     $itvTO->desconto_aplicado = 0;
                     $itvTO->valor_desconto = 0;
                     $itvTO->qtd = 1;
                     $itvTO->valor_real_item = $servico->vlr_procedimento;
                     $itvTO->vlr_custo = 0;
                     $itvTO->perc_imposto_compra = 0;
                     $itvTO->perc_desconto_compra = 0;
                     $itvTO->perc_margem_aplicada = 0;
                     $itvTO->id_procedimento = $servico->id;
                     $itvTO->id_status_procedimento = $servico->cod_status_servico;
                     $itvDao = new ItemVendaDao();
                     $osTO->servicos[$key]->id = $itvDao->saveItemVenda($itvTO);
                     if (!$osTO->servicos[$key]->id) {
                         Flight::halt(500, 'Erro ao associar o serviço [' . $servico->dsc_procedimento . '] na venda');
                     }
                 }
             }
             // Grava os produtos na venda
             if (count($osTO->produtos) > 0) {
                 foreach ($osTO->produtos as $key => $produto) {
                     $itvTO = new ItemVendaTO();
                     $itvTO->id_venda = $venTO->id;
                     $itvTO->id_produto = $produto->id_produto;
                     $itvTO->desconto_aplicado = 0;
                     $itvTO->valor_desconto = 0;
                     $itvTO->qtd = $produto->qtd_pedido;
                     $itvTO->valor_real_item = $produto->vlr_venda_varejo;
                     $itvTO->vlr_custo = $produto->vlr_custo;
                     $itvTO->perc_imposto_compra = 0;
                     $itvTO->perc_desconto_compra = 0;
                     $itvTO->perc_margem_aplicada = $produto->margem_varejo;
                     $itvDao = new ItemVendaDao();
                     $osTO->produtos[$key]->id = $itvDao->saveItemVenda($itvTO);
                     if (!$osTO->produtos[$key]->id) {
                         Flight::halt(500, 'Erro ao associar o produto [' . $produto->nome . '] na venda');
                     }
                 }
             }
             // Grava a Ordem de Serviço
             $atdTO = new AtendimentoTO();
             $atdTO->id_empreendimento = $osTO->id_empreendimento;
             $atdTO->id_paciente = $osTO->cliente->id;
             $atdTO->dta_entrada = $osTO->dta_ordem_servico;
             $atdTO->id_usuario_entrada = $osTO->criador->id;
             $atdTO->id_status = $osTO->cod_status_servico;
             $atdDao = new AtendimentoDao();
             $atdTO->id = $atdDao->saveAtendimento($atdTO);
             if (!$atdTO->id) {
                 Flight::halt(500, 'Erro ao salvar as informações do serviço');
             } else {
                 // Associa a Ordem de Serviço a Venda
                 if (count($osTO->servicos) > 0) {
                     foreach ($osTO->servicos as $key => $servico) {
                         if (!$atdDao->gravarAtendimentoVenda($atdTO->id, $venTO->id, $servico->id)) {
                             Flight::halt(500, 'Erro ao associar o serviço a venda');
                         }
                     }
                 }
                 if (count($osTO->produtos) > 0) {
                     foreach ($osTO->produtos as $key => $produto) {
                         if (!$atdDao->gravarAtendimentoVenda($atdTO->id, $venTO->id, $produto->id)) {
                             Flight::halt(500, 'Erro ao associar o produto a venda');
                         }
                     }
                 }
             }
             $status_code = 201;
         }
     } else {
         $venda_confirmada = $osTO->cod_status_servico == "4" ? 0 : 1;
         $id_status_venda = $osTO->cod_status_servico == "4" ? 5 : 6;
         $flg_excluido = $osTO->cod_status_servico == "5" ? 1 : 0;
         // Atualiza os dados da venda
         $venDao = new VendaDao();
         if ($venDao->updateVendaData($osTO->cliente->id, $venda_confirmada, $id_status_venda, $flg_excluido, $osTO->id_venda)) {
             // Remove todos os servicos e produtos da venda
             $itvDao = new ItemVendaDao();
             if ($itvDao->deleteItemsByIdVenda($osTO->id_venda)) {
                 // Grava os servicos na venda
                 if (count($osTO->servicos) > 0) {
                     foreach ($osTO->servicos as $key => $servico) {
                         $itvTO = new ItemVendaTO();
                         $itvTO->id_venda = $osTO->id_venda;
                         $itvTO->id_produto = NULL;
                         $itvTO->desconto_aplicado = 0;
                         $itvTO->valor_desconto = 0;
                         $itvTO->qtd = 1;
                         $itvTO->valor_real_item = $servico->vlr_procedimento;
                         $itvTO->vlr_custo = 0;
                         $itvTO->perc_imposto_compra = 0;
                         $itvTO->perc_desconto_compra = 0;
                         $itvTO->perc_margem_aplicada = 0;
                         $itvTO->id_procedimento = $servico->id;
                         $itvTO->id_status_procedimento = $servico->cod_status_servico;
                         $osTO->servicos[$key]->id = $itvDao->saveItemVenda($itvTO);
                         if (!$osTO->servicos[$key]->id) {
                             Flight::halt(500, 'Erro ao associar o serviço [' . $servico->dsc_procedimento . '] na venda');
                         }
                     }
                 }
                 // Grava os produtos na venda
                 if (count($osTO->produtos) > 0) {
                     foreach ($osTO->produtos as $key => $produto) {
                         $itvTO = new ItemVendaTO();
                         $itvTO->id_venda = $osTO->id_venda;
                         $itvTO->id_produto = $produto->id_produto;
                         $itvTO->desconto_aplicado = 0;
                         $itvTO->valor_desconto = 0;
                         $itvTO->qtd = $produto->qtd_pedido;
                         $itvTO->valor_real_item = $produto->vlr_venda_varejo;
                         $itvTO->vlr_custo = $produto->vlr_custo;
                         $itvTO->perc_imposto_compra = 0;
                         $itvTO->perc_desconto_compra = 0;
                         $itvTO->perc_margem_aplicada = $produto->margem_varejo;
                         $osTO->produtos[$key]->id = $itvDao->saveItemVenda($itvTO);
                         if (!$osTO->produtos[$key]->id) {
                             Flight::halt(500, 'Erro ao associar o produto [' . $produto->nome . '] na venda');
                         }
                     }
                 }
                 // Atualiza os dados da Ordem de Serviço
                 $atdTO = new StdClass();
                 $atdTO->id_paciente = $osTO->cliente->id;
                 $atdTO->id_status = $osTO->cod_status_servico;
                 $atdDao = new AtendimentoDao();
                 if ($atdDao->updateAtendimento($atdTO, 'id=' . $osTO->id)) {
                     // Remove todos os servicos e produtos da ordem de serviço
                     $atdDao->deleteItemsByIdAtendimento($osTO->id);
                     // Associa a Ordem de Serviço a Venda
                     if (count($osTO->servicos) > 0) {
                         foreach ($osTO->servicos as $key => $servico) {
                             if (!$atdDao->gravarAtendimentoVenda($osTO->id, $osTO->id_venda, $servico->id)) {
                                 Flight::halt(500, 'Erro ao associar o serviço a venda');
                             }
                         }
                     }
                     if (count($osTO->produtos) > 0) {
                         foreach ($osTO->produtos as $key => $produto) {
                             if (!$atdDao->gravarAtendimentoVenda($osTO->id, $osTO->id_venda, $produto->id)) {
                                 Flight::halt(500, 'Erro ao associar o produto a venda');
                             }
                         }
                     }
                     $status_code = 200;
                 } else {
                     Flight::halt(500, 'Erro ao atualizar os dados da ordem de serviço');
                 }
             } else {
                 Flight::halt(500, 'Erro ao remover os servicos e produtos da venda');
             }
         } else {
             Flight::halt(500, 'Erro ao atualizar os dados da venda');
         }
     }
     // Grava a movimentação de caixa
     if ($osTO->cod_status_servico == "6") {
         $movCxaTO = new MovimentacaoCaixaTO();
         $movCxaTO->id_abertura_caixa = $osTO->id_abertura_caixa;
         $movCxaTO->id_plano_conta = $osTO->id_plano_conta;
         $movCxaTO->id_tipo_movimentacao = 5;
         $movCxaTO->dsc_movimentacao = 'Venda';
         $movCxaTO->id_venda = $osTO->id_venda;
         $movCxaTO->para_receber = $osTO->vlr_total_os;
         $movCxaTO->dta_movimentacao = $osTO->dta_ordem_servico;
         $movCxaDao = new MovimentacaoCaixaDao();
         if (!$movCxaDao->saveMovimentacao($movCxaTO)) {
             Flight::halt(500, 'erro ao inserir movimentacao');
         }
     }
     Flight::halt($status_code, 'Operação realizada com sucesso!');
 }