Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
third-party
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cooperatic-foodcoops
third-party
Commits
a7f142e4
Commit
a7f142e4
authored
Mar 09, 2022
by
Etienne Freiss
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
develop
parent
5cfdcae6
Pipeline
#1897
passed with stage
in 1 minute 28 seconds
Changes
8
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
143 additions
and
36 deletions
+143
-36
models.py
members/models.py
+32
-4
member.css
members/static/css/member.css
+3
-2
members.js
members/static/js/members.js
+75
-23
views.py
members/views.py
+8
-2
members-space-shifts-exchange.css
members_space/static/css/members-space-shifts-exchange.css
+4
-2
members-space-shifts-exchange.js
members_space/static/js/members-space-shifts-exchange.js
+7
-1
index.html
templates/members/index.html
+12
-0
index.html
templates/members_space/index.html
+2
-2
No files found.
members/models.py
View file @
a7f142e4
...
...
@@ -1198,7 +1198,7 @@ class CagetteServices(models.Model):
)
.
total_seconds
()
/
60
>
default_acceptable_minutes_after_shift_begins
if
with_members
is
True
:
cond
=
[[
'id'
,
'in'
,
s
[
'registration_ids'
]],
[
'state'
,
'not in'
,
[
'cancel'
,
'waiting'
,
'draft'
]]]
fields
=
[
'partner_id'
,
'shift_type'
,
'state'
,
'is_late'
]
fields
=
[
'partner_id'
,
'shift_type'
,
'state'
,
'is_late'
,
'associate_registered'
]
members
=
api
.
search_read
(
'shift.registration'
,
cond
,
fields
)
s
[
'members'
]
=
sorted
(
members
,
key
=
lambda
x
:
x
[
'partner_id'
][
0
])
if
len
(
s
[
'members'
])
>
0
:
...
...
@@ -1207,22 +1207,27 @@ class CagetteServices(models.Model):
for
m
in
s
[
'members'
]:
mids
.
append
(
m
[
'partner_id'
][
0
])
cond
=
[[
'parent_id'
,
'in'
,
mids
]]
fields
=
[
'parent_id'
,
'name'
]
fields
=
[
'
id'
,
'
parent_id'
,
'name'
]
associated
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
if
len
(
associated
)
>
0
:
for
m
in
s
[
'members'
]:
for
a
in
associated
:
if
int
(
a
[
'parent_id'
][
0
])
==
int
(
m
[
'partner_id'
][
0
]):
m
[
'partner_name'
]
=
m
[
'partner_id'
][
1
]
m
[
'partner_id'
][
1
]
+=
' en binôme avec '
+
a
[
'name'
]
m
[
'associate_name'
]
=
str
(
a
[
'id'
])
+
' - '
+
a
[
'name'
]
return
services
@staticmethod
def
registration_done
(
registration_id
,
overrided_date
=
""
):
def
registration_done
(
registration_id
,
overrided_date
=
""
,
typeAction
=
""
):
"""Equivalent to click present in presence form."""
api
=
OdooAPI
()
f
=
{
'state'
:
'done'
}
if
(
typeAction
!=
"normal"
and
typeAction
!=
""
):
f
[
'associate_registered'
]
=
typeAction
late_mode
=
getattr
(
settings
,
'ENTRANCE_WITH_LATE_MODE'
,
False
)
if
late_mode
is
True
:
# services = CagetteServices.get_services_at_time('14:28',0, with_members=False)
...
...
@@ -1244,7 +1249,14 @@ class CagetteServices(models.Model):
return
api
.
update
(
'shift.registration'
,
[
int
(
registration_id
)],
f
)
@staticmethod
def
record_rattrapage
(
mid
,
sid
,
stid
):
def
registration_cancel
(
registration_id
,
overrided_date
=
""
):
api
=
OdooAPI
()
f
=
{
'state'
:
'open'
}
return
api
.
update
(
'shift.registration'
,
[
int
(
registration_id
)],
f
)
@staticmethod
def
record_rattrapage
(
mid
,
sid
,
stid
,
typeAction
):
"""Add a shift registration for member mid.
(shift sid, shift ticket stid)
...
...
@@ -1260,6 +1272,8 @@ class CagetteServices(models.Model):
"state"
:
'open'
}
reg_id
=
api
.
create
(
'shift.registration'
,
fields
)
f
=
{
'state'
:
'done'
}
if
(
typeAction
!=
"normal"
and
typeAction
!=
""
):
f
[
'associate_registered'
]
=
typeAction
return
api
.
update
(
'shift.registration'
,
[
int
(
reg_id
)],
f
)
@staticmethod
...
...
@@ -1275,6 +1289,20 @@ class CagetteServices(models.Model):
# let authorized people time to set presence for those who came in late
end_date
=
now
-
datetime
.
timedelta
(
hours
=
2
)
api
=
OdooAPI
()
# Let's start by adding an extra shift to associated member who came together
cond
=
[[
'date_begin'
,
'>='
,
date_24h_before
.
isoformat
()],
[
'date_begin'
,
'<='
,
end_date
.
isoformat
()],
[
'state'
,
'='
,
'done'
],
[
'associate_registered'
,
'='
,
'both'
]]
fields
=
[
'state'
,
'partner_id'
,
'date_begin'
]
res
=
api
.
search_read
(
'shift.registration'
,
cond
,
fields
)
for
r
in
res
:
cond
=
[[
'id'
,
'='
,
r
[
'partner_id'
][
0
]]]
fields
=
[
'id'
,
'extra_shift_done'
]
res
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
f
=
{
'extra_shift_done'
:
res
[
0
][
'extra_shift_done'
]
+
1
}
api
.
update
(
'res.partner'
,
[
r
[
'partner_id'
][
0
]],
f
)
absence_status
=
'excused'
res_c
=
api
.
search_read
(
'ir.config_parameter'
,
[[
'key'
,
'='
,
'lacagette_membership.absence_status'
]],
...
...
members/static/css/member.css
View file @
a7f142e4
...
...
@@ -44,8 +44,9 @@ h1 .member_name {font-weight: bold;}
.members_list
{
list-style
:
none
;}
.members_list
li
{
display
:
block
;
margin-bottom
:
5px
;}
.members_list
li
.btn--inverse
{
background
:
#449d44
;
c
ursor
:
not-allowed
;
c
olor
:
#FFF
;
}
.members_list
li
.btn--inverse
{
background
:
#449d44
;
color
:
#FFF
;
}
.members_list
li
.btn--inverse.late
{
background-color
:
#de9b00
;
color
:
white
}
.members_list
li
.btn--inverse.both
{
background-color
:
#0275d8
;
color
:
white
}
#service_entry_success
{
font-size
:
x-large
;}
#service_entry_success
.explanations
{
margin
:
25px
0
;
font-size
:
18px
;}
...
...
@@ -64,7 +65,7 @@ h1 .member_name {font-weight: bold;}
#service_en_cours
.info
a
{
line-height
:
24px
;
font-size
:
14px
;
margin-top
:
15px
;}
.outside_list
a
{
margin-left
:
15px
;}
#rattrapage_1
.advice
{
margin-top
:
15px
;}
.btn.present
{
background
:
#50C878
;}
.btn.present
{
background
:
#50C878
;
color
:
white
!important
;
font-weight
:
bold
;
}
.btn.return
{
background
:
#ff3333
;
color
:
#FFF
!important
;
margin-top
:
25px
;}
.msg-big
{
font-size
:
xx-large
;
background
:
#fff
;
padding
:
25px
;
text-align
:
center
;}
...
...
members/static/js/members.js
View file @
a7f142e4
...
...
@@ -31,12 +31,14 @@ var search_field = $('input[name="search_string"]');
var
shift_title
=
$
(
'#current_shift_title'
);
var
shift_members
=
$
(
'#current_shift_members'
);
var
service_validation
=
$
(
'#service_validation'
);
var
associated_service_validation
=
$
(
'#associated_service_validation'
);
var
validation_last_call
=
0
;
var
rattrapage_wanted
=
$
(
'[data-next="rattrapage_1"]'
);
var
webcam_is_attached
=
false
;
var
photo_advice
=
$
(
'#photo_advice'
);
var
photo_studio
=
$
(
'#photo_studio'
);
var
coop_info
=
$
(
'.coop-info'
);
var
service_data
=
null
;
const
missed_begin_msg
=
$
(
'#missed_begin_msg'
).
html
();
...
...
@@ -264,7 +266,7 @@ function get_simple_service_name(s) {
}
function
move_service_validation_to
(
page
)
{
service_
validation
.
find
(
'.btn'
).
data
(
'stid'
,
'0'
)
;
service_
data
.
stid
=
0
;
page
.
find
(
'.validation_wrapper'
)
.
append
(
service_validation
.
detach
());
}
...
...
@@ -285,10 +287,14 @@ function fill_service_entry(s) {
var
li_data
=
""
;
if
(
e
.
state
==
"done"
)
{
li_data
=
' data-rid="'
+
e
.
id
+
'" data-mid="'
+
e
.
partner_id
[
0
]
+
'"'
;
li_class
+=
"--inverse"
;
if
(
e
.
is_late
==
true
)
{
li_class
+=
" late"
;
}
if
(
e
.
associate_registered
==
'both'
)
{
li_class
+=
" both"
;
}
}
else
{
li_data
=
' data-rid="'
+
e
.
id
+
'" data-mid="'
+
e
.
partner_id
[
0
]
+
'"'
;
}
...
...
@@ -321,13 +327,29 @@ function clean_service_entry() {
function
fill_service_validation
(
rid
,
coop_num_name
,
coop_id
)
{
var
coop_name_elts
=
coop_num_name
.
split
(
' - '
);
for
(
member
of
loaded_services
[
0
].
members
)
{
if
(
member
.
id
==
rid
)
{
if
(
member
.
associate_name
)
{
pages
.
service_entry_validation
.
find
(
'#service_validation'
).
hide
();
pages
.
service_entry_validation
.
find
(
'#associated_service_validation'
).
show
();
pages
.
service_entry_validation
.
find
(
'#associated_btn'
).
text
(
member
.
associate_name
);
pages
.
service_entry_validation
.
find
(
'#partner_btn'
).
text
(
member
.
partner_name
);
}
else
{
pages
.
service_entry_validation
.
find
(
'#associated_service_validation'
).
hide
();
pages
.
service_entry_validation
.
find
(
'#service_validation'
).
show
();
}
}
}
service_data
=
{
rid
:
rid
,
sid
:
selected_service
.
id
,
mid
:
coop_id
};
pages
.
service_entry_validation
.
find
(
'span.member_name'
).
text
(
coop_name_elts
[
1
]);
move_service_validation_to
(
pages
.
service_entry_validation
);
service_validation
.
find
(
'.btn'
)
.
data
(
'rid'
,
rid
)
.
data
(
'sid'
,
selected_service
.
id
)
.
data
(
'mid'
,
coop_id
);
}
function
select_possible_service
()
{
...
...
@@ -372,7 +394,6 @@ function get_service_entry_data() {
dataType
:
'json'
})
.
done
(
function
(
rData
)
{
//console.log(rData);
info_place
.
text
(
''
);
var
page_title
=
pages
.
service_entry
.
find
(
'h1'
);
...
...
@@ -397,6 +418,7 @@ function get_service_entry_data() {
page_title
.
text
(
'Quel est ton service ?'
);
}
else
{
loaded_services
=
rData
.
res
;
fill_service_entry
(
rData
.
res
[
0
]);
}
}
...
...
@@ -443,22 +465,21 @@ function fill_service_entry_sucess(member) {
}
function
record_service_presence
()
{
function
record_service_presence
(
e
)
{
var
d
=
new
Date
();
var
elapsed_since_last_call
=
d
.
getTime
()
-
validation_last_call
;
if
(
elapsed_since_last_call
>
1000
0
)
{
if
(
elapsed_since_last_call
>
1000
)
{
loading2
.
show
();
validation_last_call
=
d
.
getTime
();
var
clicked
=
service_validation
.
find
(
'.btn'
);
var
rid
=
clicked
.
data
(
'rid'
);
var
mid
=
clicked
.
data
(
'mid'
);
var
sid
=
clicked
.
data
(
'sid'
);
var
stid
=
clicked
.
data
(
'stid'
);
var
rid
=
service_data
.
rid
;
var
mid
=
service_data
.
mid
;
var
sid
=
service_data
.
sid
;
var
stid
=
service_data
.
stid
;
post_form
(
'/members/service_presence/'
,
{
'mid'
:
mid
,
'rid'
:
rid
,
'sid'
:
sid
,
'stid'
:
stid
},
{
'mid'
:
mid
,
'rid'
:
rid
,
'sid'
:
sid
,
'stid'
:
stid
,
'cancel'
:
false
,
'type'
:
e
.
data
.
type
},
function
(
err
,
rData
)
{
if
(
!
err
)
{
var
res
=
rData
.
res
;
...
...
@@ -480,6 +501,28 @@ function record_service_presence() {
}
}
function
cancel_service_presence
(
mid
,
rid
)
{
var
d
=
new
Date
();
var
elapsed_since_last_call
=
d
.
getTime
()
-
validation_last_call
;
if
(
elapsed_since_last_call
>
1000
)
{
loading2
.
show
();
validation_last_call
=
d
.
getTime
();
var
sid
=
selected_service
.
id
;
post_form
(
'/members/service_presence/'
,
{
'mid'
:
mid
,
'rid'
:
rid
,
'sid'
:
sid
,
'stid'
:
0
,
'cancel'
:
true
},
function
(
err
)
{
if
(
!
err
)
{
get_service_entry_data
();
}
loading2
.
hide
();
}
);
}
}
function
fill_rattrapage_2
()
{
pages
.
rattrapage_2
.
find
(
'span.member_name'
).
text
(
current_displayed_member
.
name
);
var
msg
=
"Bienvenue pour ton rattrapage !"
;
...
...
@@ -494,13 +537,11 @@ function fill_rattrapage_2() {
msg
=
"Tu es en désincrit.e ... La situation doit être réglée avez le Bureau des Membres"
;
}
else
{
move_service_validation_to
(
pages
.
rattrapage_2
);
service_validation
.
find
(
'.btn'
)
.
data
(
'rid'
,
0
)
.
data
(
'sid'
,
selected_service
.
id
)
.
data
(
'stid'
,
shift_ticket_id
)
.
data
(
'mid'
,
current_displayed_member
.
id
);
service_data
=
{
rid
:
0
,
sid
:
selected_service
.
id
,
stid
:
shift_ticket_id
,
mid
:
current_displayed_member
.
id
};
}
pages
.
rattrapage_2
.
find
(
'h2'
).
text
(
msg
);
...
...
@@ -641,7 +682,10 @@ $('.btn[data-next]').click(function() {
});
service_validation
.
on
(
"click"
,
".btn"
,
record_service_presence
);
service_validation
.
on
(
"click"
,
".btn"
,
{
type
:
'normal'
},
record_service_presence
);
associated_service_validation
.
on
(
"click"
,
"#associated_btn"
,
{
type
:
'associate'
},
record_service_presence
);
associated_service_validation
.
on
(
"click"
,
"#partner_btn"
,
{
type
:
'partner'
},
record_service_presence
);
associated_service_validation
.
on
(
"click"
,
"#both_btn"
,
{
type
:
'both'
},
record_service_presence
);
shift_members
.
on
(
"click"
,
'.btn[data-rid]'
,
function
()
{
var
clicked
=
$
(
this
);
...
...
@@ -653,6 +697,14 @@ shift_members.on("click", '.btn[data-rid]', function() {
});
shift_members
.
on
(
"click"
,
'.btn--inverse'
,
function
()
{
var
clicked
=
$
(
this
);
var
rid
=
clicked
.
data
(
'rid'
);
var
mid
=
clicked
.
data
(
'mid'
);
cancel_service_presence
(
mid
,
rid
);
});
pages
.
shopping_entry
.
on
(
'css'
,
function
()
{
photo_advice
.
hide
();
photo_studio
.
hide
();
...
...
members/views.py
View file @
a7f142e4
...
...
@@ -277,6 +277,9 @@ def record_service_presence(request):
mid
=
int
(
request
.
POST
.
get
(
"mid"
,
0
))
# member id
sid
=
int
(
request
.
POST
.
get
(
"sid"
,
0
))
# shift id
stid
=
int
(
request
.
POST
.
get
(
"stid"
,
0
))
# shift_ticket_id
cancel
=
request
.
POST
.
get
(
"cancel"
)
==
'true'
typeAction
=
str
(
request
.
POST
.
get
(
"type"
))
app_env
=
getattr
(
settings
,
'APP_ENV'
,
"prod"
)
if
(
rid
>
-
1
and
mid
>
0
):
overrided_date
=
""
...
...
@@ -286,14 +289,15 @@ def record_service_presence(request):
if
o_date
:
overrided_date
=
re
.
sub
(
r'(
%20
)'
,
' '
,
o_date
.
group
(
1
))
if
(
not
cancel
):
# rid = 0 => C'est un rattrapage, sur le service
if
sid
>
0
and
stid
>
0
:
# Add member to service and take presence into account
res
[
'rattrapage'
]
=
CagetteServices
.
record_rattrapage
(
mid
,
sid
,
stid
)
res
[
'rattrapage'
]
=
CagetteServices
.
record_rattrapage
(
mid
,
sid
,
stid
,
typeAction
)
if
res
[
'rattrapage'
]
is
True
:
res
[
'update'
]
=
'ok'
else
:
if
(
CagetteServices
.
registration_done
(
rid
,
overrided_date
)
is
True
):
if
(
CagetteServices
.
registration_done
(
rid
,
overrided_date
,
typeAction
)
is
True
):
res
[
'update'
]
=
'ok'
else
:
res
[
'update'
]
=
'ko'
...
...
@@ -308,6 +312,8 @@ def record_service_presence(request):
del
m
[
'shifts'
]
m
[
'next_shift'
]
=
next_shift
res
[
'member'
]
=
m
else
:
CagetteServices
.
registration_cancel
(
rid
,
overrided_date
)
except
Exception
as
e
:
res
[
'error'
]
=
str
(
e
)
return
JsonResponse
({
'res'
:
res
})
...
...
members_space/static/css/members-space-shifts-exchange.css
View file @
a7f142e4
...
...
@@ -69,7 +69,6 @@
display
:
flex
;
align-items
:
center
;
margin-left
:
15px
;
margin
:
0.75rem
0
;
border-radius
:
5px
;
margin-right
:
15px
;
}
...
...
@@ -86,10 +85,13 @@
display
:
flex
;
align-items
:
center
;
margin-left
:
15px
;
margin
:
0.75rem
0
;
border-radius
:
5px
;
}
.selectable_shift
{
margin
:
1rem
0
;
}
/* -- Calendar screen, makeups message */
...
...
members_space/static/js/members-space-shifts-exchange.js
View file @
a7f142e4
...
...
@@ -36,7 +36,7 @@ function add_or_change_shift(new_shift_id) {
+
'&idPartner='
+
partner_data
.
partner_id
+
'&shift_type='
+
partner_data
.
shift_type
+
'&verif_token='
+
partner_data
.
verif_token
;
}
else
if
(
partner_data
.
is_associated_people
===
"True"
&&
block_actions_for_attached_people
===
"False"
)
{
}
else
if
(
partner_data
.
is_associated_people
===
"True"
&&
block_actions_for_attached_people
===
"False"
)
{
tData
=
'idNewShift='
+
new_shift_id
+
'&idPartner='
+
partner_data
.
parent_id
+
'&shift_type='
+
partner_data
.
shift_type
...
...
@@ -178,7 +178,9 @@ function init_shifts_list() {
shift_line_template
.
find
(
'.affect_associate_registered'
).
attr
(
'id'
,
'shift_id_'
+
shift
.
id
);
if
(
shift
.
associate_registered
===
"both"
)
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
text
(
"Les deux"
);
shift_line_template
.
find
(
'.affect_associate_registered'
).
addClass
(
'btn--success'
);
}
else
if
(
shift
.
associate_registered
===
"partner"
)
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
addClass
(
'btn--success'
);
if
(
partner_data
.
associated_partner_id
!==
"False"
)
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
text
(
partner_data
.
name
);
}
else
{
...
...
@@ -186,6 +188,7 @@ function init_shifts_list() {
}
}
else
if
(
shift
.
associate_registered
===
"associate"
)
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
addClass
(
'btn--success'
);
if
(
partner_data
.
associated_partner_id
!==
"False"
)
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
text
(
partner_data
.
associated_partner_name
);
}
else
{
...
...
@@ -193,10 +196,13 @@ function init_shifts_list() {
}
}
else
{
shift_line_template
.
find
(
'.affect_associate_registered'
).
text
(
"A déterminer"
);
shift_line_template
.
find
(
'.affect_associate_registered'
).
addClass
(
'btn--danger'
);
}
}
$
(
"#shifts_list"
).
append
(
shift_line_template
.
html
());
shift_line_template
.
find
(
'.affect_associate_registered'
).
removeClass
(
'btn--danger'
);
shift_line_template
.
find
(
'.affect_associate_registered'
).
removeClass
(
'btn--success'
);
}
$
(
".selectable_shift_line"
).
on
(
"click"
,
function
(
e
)
{
...
...
templates/members/index.html
View file @
a7f142e4
...
...
@@ -181,6 +181,18 @@
<span
class=
"loading2"
><img
width=
"75"
src=
"/static/img/Pedro_luis_romani_ruiz.gif"
alt=
"Chargement en cours...."
/></span>
<div
class=
"col-2"
></div>
</section>
<div
id=
"associated_service_validation"
>
<p
class=
"col-6 txtcenter"
>
Qui est présent à ce service ?
</p>
<section
class=
"col-6 grid-6 has-gutter"
>
<div
class=
"col-2"
></div>
<a
id=
"associated_btn"
class=
" btn present"
>
Membre
</a>
<a
id=
"partner_btn"
class=
" btn present"
>
Associé
</a>
<a
id=
"both_btn"
class=
" btn present"
>
Les deux
</a>
<span
class=
"loading2"
><img
width=
"75"
src=
"/static/img/Pedro_luis_romani_ruiz.gif"
alt=
"Chargement en cours...."
/></span>
<div
class=
"col-2"
></div>
</section>
</div>
</div>
<div
class=
"col-2"
></div>
<a
class=
"btn col-2 return"
data-next=
"service_entry"
>
Retour
</a>
...
...
templates/members_space/index.html
View file @
a7f142e4
...
...
@@ -36,14 +36,14 @@
</div>
<div
id=
"selectable_shift_line_template"
>
<div
class=
"d-flex"
>
<div
class=
"d-flex
selectable_shift
"
>
<div
class=
"selectable_shift_line btn--primary"
>
<input
type=
"checkbox"
class=
"checkbox"
>
<div
class=
"selectable_shift_line_text"
>
<span
class=
"shift_line_date"
></span>
-
<span
class=
"shift_line_time"
></span>
</div>
</div>
<div
class=
"affect_associate_registered
button--warning
"
>
<div
class=
"affect_associate_registered"
>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment