MyCo/inc/myco_objects.js

718 lines
18 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function GroupList() {
lastChange=0;
this.loadFromLocalStorage=function() {
if (jQuery.type(localStorage.groups)!='undefined') {
try {
var data=JSON.parse(localStorage.groups);
this.lastChange=data.lastChange;
for (el in data.groups) {
this[el]=new Group(el,false,data.groups[el]);
}
}
catch(e) {
for (el in this) {
if (this.isGroup(this[el])) {
delete this[el];
}
}
myconfirm('Erreur en chargeant les données locales. On les purges ?',
function(data) {
delete localStorage.groups;
location.reload();
}
);
}
}
}
this.export=function() {
return {
'lastChange': this.lastChange,
'groups': this.each(function(idx,group) {
return group.export();
})
};
}
this.import=function(groups) {
ret={};
for (el in this) {
if (this.isGroup(this[el])) {
delete ret[el];
}
}
this.lastChange=groups.lastChange;
for (el in groups.groups) {
this[el]=new Group(el,false,groups.groups[el]);
}
return true;
}
this.save=function() {
localStorage.groups=JSON.stringify(this.export());
}
this.each=function(fct) {
var idx=0;
var ret={};
for (el in this) {
if(this.isGroup(this[el])) {
ret[el]=fct(idx++,this[el]);
}
}
return ret;
}
this.count=function() {
len=0;
this.each(function(idx,group) {
len=len+1;
});
return len;
}
this.isGroup=function(el) {
return (jQuery.type(el)=='object' && jQuery.type(el.isGroup)=='function' && el.isGroup());
}
this.byName=function(name) {
for (el in this) {
if(this.isGroup(this[el])) {
if (this[el].name==name) {
return this[el];
}
}
}
return false;
}
this.removeGroup=function(uuid) {
if (this.isGroup(this[uuid])) {
delete this[uuid];
return true;
}
return false;
}
this.balances=function(fct) {
return this.each(function(idx,group) {
bal=group.balance();
bal.name=group.name;
return bal;
});
}
this.newGroup=function(name,uuid) {
var uuid=uuid||generate_uuid();
this[uuid]=new Group(uuid,name);
return uuid;
}
}
function Group(uuid,name,data) {
this.uuid=uuid || generate_uuid();
this.name=name || false;
this.contributors={};
this.deletedContributors={};
this.contributions={};
this.deletedContributions={};
this.categories={};
this.deletedCategories={};
this.isGroup=function() {
return true;
}
this.export=function() {
var contributors={};
for (email in this.contributors) {
contributors[email]=this.contributors[email].export();
}
var contributions={}
for (uuid in this.contributions) {
contributions[uuid]=this.contributions[uuid].export();
}
var categories={}
for (uuid in this.categories) {
categories[uuid]=this.categories[uuid].export();
}
return {
'uuid': this.uuid,
'name': encodeURIComponent(this.name),
'contributors': contributors,
'deletedContributors': this.deletedContributors,
'contributions': contributions,
'deletedContributions': this.deletedContributions,
'categories': categories,
'deletedCategories': this.deletedCategories
};
}
/*
* Contributors
*/
this.removeContributor=function(c) {
this.deletedContributors[c.email]=c.export();
time=new Date().getTime();
this.deletedContributors[c.email].deletionTime=time;
contributions=this.contributionsByContributorEmail(c.email);
for (idx in contributions) {
this.deleteContribution(contributions[idx].uuid,time);
}
delete this.contributors[c.email];
return true;
}
this.restoreContributor=function(email) {
if (email in this.contributors) return;
if (! email in this.deletedContributors) return;
this.contributors[email]=this.importContributor(this.deletedContributors[email]);
contributions=this.deletedContributionsByContributorEmail(email);
for (idx in contributions) {
if (contributions[idx].lastChange==this.deletedContributors[email].deletionTime) {
this.restoreContribution(contributions[idx].uuid);
}
}
delete this.deletedContributors[email];
return true;
}
this.getDeletedContributors=function() {
var ret=[];
for (email in this.deletedContributors) {
ret.push(this.importContributor(this.deletedContributors[email]));
}
return ret;
}
this.contributorByName=function(name) {
for (email in this.contributors) {
if (this.contributors[email].name == name) return this.contributors[email];
}
return undefined;
}
this.contributorByEmail=function(email) {
if (jQuery.type(this.contributors[email])!='undefined') {
return this.contributors[email];
}
return undefined;
}
this.addContributor=function(c) {
this.contributors[c.email]=c;
}
this.replaceContributor=function(email,c) {
delete this.contributors[email];
this.contributors[c.email]=c;
}
this.importContributor=function(data) {
return new Contributor(
decodeURIComponent(data.name),
data.email
);
}
/*
* Contributions
*/
this.contributionsByContributorEmail=function(email) {
var ret=[];
for (uuid in this.contributions) {
if (this.contributions[uuid].contributor.email==email) {
ret.push(this.contributions[uuid]);
}
}
return this.sortContributionsByDate(ret);
}
this.sortContributionsByDate=function(contributions) {
contributions.sort(function(a,b) {
if (a.date==b.date) {
return 0;
}
else if(a.date<b.date) {
return 1;
}
else {
return -1;
}
});
return contributions;
}
this.deletedContributionsByContributorEmail=function(email) {
var ret=[];
for (uuid in this.deletedContributions) {
if (this.deletedContributions[uuid].contributor==email) {
ret.push(new Contribution(
this.contributorByEmail(email),
this.deletedContributions[uuid].cost,
decodeURIComponent(this.deletedContributions[uuid].title),
this.deletedContributions[uuid].date,
this.deletedContributions[uuid].category,
uuid,
this.deletedContributions[uuid].lastChange
));
}
}
ret.sort(function(a,b) {
if (a.lastChange==b.lastChange) {
return 0;
}
else if(a.lastChange<b.lastChange) {
return -1;
}
else {
return 1;
}
});
return ret;
}
this.addContribution=function(c) {
this.contributions[c.uuid]=c;
}
this.updateContribution=function(uuid,c) {
c.uuid=uuid;
this.contributions[uuid]=c;
}
this.deleteContribution=function(uuid,time) {
this.contributions[uuid].lastChange=time || new Date().getTime();
this.deletedContributions[uuid]=this.contributions[uuid].export();
delete this.contributions[uuid];
}
this.restoreContribution=function(uuid) {
this.deletedContributions[uuid].lastChange=new Date().getTime();
this.contributions[uuid]=this.importContribution(this.deletedContributions[uuid]);
delete this.deletedContributions[uuid];
}
this.importContribution=function(data) {
return new Contribution(
this.contributorByEmail(data.contributor),
data.cost,
decodeURIComponent(data.title),
data.date,
data.category,
data.uuid,
data.lastChange
);
}
this.findContributionByTitleMatches=function() {
var contributions=this.contributions;
return function(q, cb) {
var matches, substrRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
var titles=[];
for (uuid in contributions) {
if (substrRegex.test(contributions[uuid].title)) {
var title=String(contributions[uuid].title).replace(/^\s+|\s+$/g, '');
if (titles.indexOf(title.toLowerCase())!=-1) {
continue;
}
titles.push(title.toLowerCase());
matches.push({
value: title,
category: contributions[uuid].category
});
}
}
cb(matches);
};
}
this.searchContributions=function(pattern,contributor) {
var ret=[];
substrRegex = new RegExp(pattern, 'i');
for (uuid in this.contributions) {
if (contributor && contributor!=this.contributions[uuid].contributor.email) {
continue;
}
if (substrRegex.test(this.contributions[uuid].title) || substrRegex.test(this.contributions[uuid].cost)) {
ret.push(this.contributions[uuid]);
}
}
return this.sortContributionsByDate(ret);
}
this.getContributionsByCategory=function (category) {
var ret={};
for (uuid in this.contributions) {
if (this.contributions[uuid].category==category.uuid) {
ret[uuid]=this.contributions[uuid];
}
}
return ret;
}
this.findUnusedCategories=function() {
var cats={};
for (uuid in this.contributions) {
cid=this.contributions[uuid].category;
if ($.type(cats[cid])=='undefined') {
cats[cid]=1;
}
else {
cats[cid]++;
}
}
var ret={};
for (cid in this.categories) {
if ($.type(cats[cid])=='undefined') {
ret[cid]=this.categories[cid];
}
}
return ret;
}
/*
* Categories
*/
this.addCategory=function(c) {
this.categories[c.uuid]=c;
}
this.updateCategory=function(uuid,c) {
c.uuid=uuid;
this.categories[uuid]=c;
}
this.deleteCategory=function(uuid,time) {
this.categories[uuid].lastChange=time || new Date().getTime();
this.deletedCategories[uuid]=this.categories[uuid].export();
delete this.categories[uuid];
}
this.restoreCategory=function(uuid) {
this.deletedCategories[uuid].lastChange=new Date().getTime();
this.categories[uuid]=this.importCategory(this.deletedCategories[uuid]);
delete this.deletedCategories[uuid];
}
this.getCategoryByName=function(name,approx) {
if(approx) {
name=String(name).replace(/^\s+|\s+$/g, '').toLowerCase();
}
for (uuid in this.categories) {
if (approx) {
if (String(this.categories[uuid].name).replace(/^\s+|\s+$/g, '').toLowerCase()==name) {
return this.categories[uuid];
}
}
else if(this.categories[uuid].name==name) {
return this.categories[uuid]
}
}
return false;
}
this.importCategory=function(data) {
return new Category(
decodeURIComponent(data.name),
data.color,
data.lastChange,
data.uuid
);
}
this.getSortedCategories=function() {
uuids=[];
for (uuid in this.categories) {
uuids.push(uuid);
}
tmp_cats=this.categories;
uuids.sort(function(a,b) {
return tmp_cats[a]['name'].localeCompare(tmp_cats[b]['name']);
});
var ret={};
for (idx in uuids) {
ret[uuids[idx]]=this.categories[uuids[idx]];
}
return ret;
}
this.getCategoriesStats=function() {
var cats={};
for (uuid in this.contributions) {
if (jQuery.type(cats[this.contributions[uuid].category])=='undefined') {
cats[this.contributions[uuid].category]=0;
}
cats[this.contributions[uuid].category]+=this.contributions[uuid].cost;
}
var data=[];
for (cid in cats) {
if (jQuery.type(this.categories[cid])!='undefined') {
data.push({
'label': this.categories[cid].name,
'data': cats[cid],
'color': this.categories[cid].color
});
}
}
return data;
}
/*
* Balance
*/
this.balance=function() {
total={}
min=-1;
max=0;
for (email in this.contributors) {
var sum=0;
cl=this.contributionsByContributorEmail(email);
for (idx in cl) {
sum+=cl[idx].cost;
}
if (min==-1 || min>sum) {
min=sum;
}
if(max<sum) {
max=sum;
}
total[email]=sum;
}
balance={}
var sum=0;
for (email in total) {
balance[email]={
'name': this.contributors[email].name,
'total': total[email],
'diff': total[email]-max,
}
sum=sum+total[email];
}
return {
'balance': balance,
'sum': sum,
'min': min,
'max': max
};
}
/*
* Contructor
*/
if (jQuery.type(data)=='object') {
try {
this.uuid=data.uuid;
this.name=data.name;
if (jQuery.type(data.contributors) == 'object') {
for (email in data.contributors) {
this.contributors[email]=this.importContributor(data.contributors[email]);
}
}
if (jQuery.type(data.deletedContributors) == 'object') {
for (email in data.deletedContributors) {
this.deletedContributors[email]=data.deletedContributors[email];
}
}
if (jQuery.type(data.contributions) == 'object') {
for (uuid in data.contributions) {
this.contributions[uuid]=this.importContribution(data.contributions[uuid]);
}
}
if (jQuery.type(data.deletedContributions) == 'object') {
for (uuid in data.deletedContributions) {
this.deletedContributions[uuid]=data.deletedContributions[uuid];
}
}
if (jQuery.type(data.categories) == 'object') {
for (uuid in data.categories) {
this.categories[uuid]=this.importCategory(data.categories[uuid]);
}
}
if (jQuery.type(data.deletedCategories) == 'object') {
for (uuid in data.deletedCategories) {
this.deletedCategories[uuid]=data.deletedCategories[uuid];
}
}
}
catch (e) {
console.log(e);
alert('Une erreur est survenue en chargeant le groupe '+this.name+' depuis le cache');
}
}
}
function Contributor(name,email) {
this.name=name;
this.email=email;
this.export=function() {
return {
'name': encodeURIComponent(this.name),
'email': this.email
};
}
}
function Category(name,color,lastChange,uuid) {
this.name=name;
this.color=color || '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6);
this.lastChange=lastChange || new Date().getTime();
this.uuid=uuid || generate_uuid();
this.export=function() {
return {
'name': encodeURIComponent(this.name),
'color': this.color,
'lastChange': this.lastChange,
'uuid': this.uuid
};
}
}
function Contribution(contributor,cost,title,date,cat,uuid,lastChange) {
this.contributor=contributor;
this.cost=cost;
this.title=title;
if (jQuery.type(date)!='date') {
date=moment(date).toDate();
}
this.date=date;
this.uuid=uuid || generate_uuid();
this.category=cat;
this.lastChange=lastChange || new Date().getTime();
this.export=function() {
return {
'contributor': this.contributor.email,
'uuid': this.uuid,
'cost': this.cost,
'title': encodeURIComponent(this.title),
'date': this.date.getTime(),
'category': this.category,
'lastChange': this.lastChange,
};
}
this.getTitle=function() {
if (jQuery.type(this.title)=='string') {
return this.title;
}
return '';
}
}
function SyncServer() {
this.url=false;
this.email=false;
this.password=false;
this.logged=false;
this.login=function(url,email,password,onsuccess,onerror) {
this.url=url;
this.email=email;
this.password=password;
try {
jQuery.getJSON(
this.url+'/login',
{'email':email,'password':password, 'time': new Date().getTime()},
function(data, textStatus) {
console.log(data);
if (textStatus=='success') {
if(jQuery.type(data.email) != 'undefined' && jQuery.type(data.name) != 'undefined') {
console.log('Login success return');
console.log(onsuccess);
onsuccess(data);
return true;
}
}
onerror(data);
}
).fail(onerror);
}
catch(e) {
if(jQuery.type(onerror)=='function') {
onerror();
}
}
}
this.subscribe=function(url,email,name,password,onsuccess,onerror) {
this.url=url;
this.email=email;
this.name=name;
this.password=password;
try {
jQuery.getJSON(
this.url+'/subscribe',
{'email':email,'name': name,'password':password, 'time': new Date().getTime()},
function(data, textStatus) {
console.log(data);
if (textStatus=='success') {
if(jQuery.type(data.email) != 'undefined' && jQuery.type(data.name) != 'undefined') {
onsuccess(data);
return true;
}
}
onerror(data);
return false;
}
).fail(onerror);
}
catch(e) {
if(jQuery.type(onerror)=='function') {
onerror();
}
}
}
this.sync=function(url,email,password,groups,onsuccess,onerror) {
this.url=url;
this.email=email;
this.password=password;
try {
jQuery.post(
this.url+'/sync',
{
'email':email,
'password':password,
'groups': JSON.stringify(groups)
},
function(data, textStatus) {
console.log(data);
if (textStatus=='success') {
if(jQuery.type(data.groups)) {
console.log('Sync success return');
onsuccess(data);
return true;
}
}
onerror(data);
},
'json'
).fail(onerror);
}
catch(e) {
if(jQuery.type(onerror)=='function') {
onerror();
}
}
}
}