2
I could use a hand! I am new to Node.JS and decided to "create a system" to put into practice what I already know and create challenges to encourage my learning! I did a beginner workshop (with Jean Carlo Suissa) that gave me a good basis, but I need "something more"!
I’ve done a lot of research, but I still can’t solve the problem below:
Schema
, ativa: {type: Boolean, default: true}
, prestacao_servico:
[ { inicio: {type: Date, default: Date.now, trim: true}
, fim: {type: Date, default: '', trim: true}
}
]
Every time a contract is renewed (activate) or the company is registered, an element will be inserted in the array prestacao_servico determining the date of beginning of this contract, with the field end having null value and boolean active will be set to true.
And when the company is shut down (deactivate) should be searched inside the array prestacao_servico the item that has the field end null (there can only be one item of this timpo in the array) and exchange its value for the closing date Date.now()
, the value of active for false.
Example:
{
"_id": "54eec2379881c0d032856dd5",
"razao_social": "Empresa 1 EIRELI me",
"__v": 3,
"contato": {
"telefone": "1212341234",
"celular": "12123451234",
"email": "[email protected]"
},
"endereco": {
"cep": "12345123",
"logradouro": "Rua A",
"bairro": "Bairro A",
"cidade": "Cidade 1",
"uf": "RJ",
"pais": "Brasil",
"complemento": "",
"numero": "123"
},
"simples_nacional": {
"codigo": "123412341234"
},
"documentos": {
"cnpj": "12123123123412",
"inscricao_estadual": "12345678"
},
"opcao": {
"sociedade": 1,
"enquadramento": 1,
"tributacao": 2
},
"prestacao_servico": [
{
"_id": "54eec2379881c0d032856dd6",
"fim": "2015-02-26T07:06:14.741Z",
"inicio": "2015-01-08T21:00:00.000Z"
},
{
"_id": "54eec305f32a497533dc8eb1",
"fim": "2015-02-26T07:08:42.451Z",
"inicio": "2015-02-26T06:53:57.543Z"
},
{
"_id": "54eec7505b3f2dd13688589d",
"fim": null,
"inicio": "2015-02-26T07:12:16.775Z"
}
],
"ativa": true
}
The company above this active ("ativa": true
) and had his contract initiated at the time 2015-02-26T07:12:16.775Z.
By disabling it, the field end, of the object whose _id is 54eec7505b3f2dd13688589d, must receive the value corresponding to "time of deactivation".
Problem:
How to locate the enterprise (for _id), then locate the item (in prestacao_servico) which has the value of end null and edit it by inserting the moment?
I already used the query {_id: req.params.id, prestacao_servico: {$elemMatch: {fim: null}}}
within the find
, but use the $elemMatch
it makes no difference because it will not have another company with the same ID, even because the field documentos.cnpj
is defined as unique.
The Aggregate did not return any result.
I found a solution, but it seems to me to be a great gambiarra:
_Model.findOne({_id: req.params.id, "prestacao_servico.fim": null}, function(err, data){
if(err) {
// ERRO
}
var count = 0
, i
;
data.prestacao_servico.forEach(function(element, index, array) {
if(element.fim === null) {
count++;
i = index;
}
});
if(count > 1) {
// ERRO
}
else {
data.prestacao_servico[i].fim = Date.now();
data
.save(function(e, d) {
if(err) {
// ERRO
}
else {
// DATA
}
});
}
});
Any hint?
SOLUTION
I followed my reasoning, applied the improvements cited by Sergio and tried to improve some aspects, too. Finally, ended like this:
var dados = req.params
, query = {_id: dados.id}
;
var promise = _Model.findOne(query).exec();
promise
.then(function(e) {
ps = e.prestacao_servico.filter(function(item) {
return !item.fim;
});
if(ps.length !== 1) throw new _SigError();
ps[0].fim = Date.now();
e.save();
return e;
})
.then(function(data) {
cb(null, data, res);
})
.then(null, function(err) {
cb(err, null, res);
});