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
e5bff7b4
Commit
e5bff7b4
authored
Jan 20, 2025
by
Yvon Kerdoncuff
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'migration-v12' into refonte_espace_membre_sc
parents
550ea71e
3277594d
Pipeline
#4065
canceled with stage
Changes
6
Pipelines
2
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
84 additions
and
46 deletions
+84
-46
admin.py
members/admin.py
+0
-0
models.py
members/models.py
+32
-34
views.py
members_space/views.py
+1
-1
fonctions.py
shifts/fonctions.py
+46
-3
models.py
shifts/models.py
+0
-0
views.py
shifts/views.py
+5
-8
No files found.
members/admin.py
View file @
e5bff7b4
This diff is collapsed.
Click to expand it.
members/models.py
View file @
e5bff7b4
...
...
@@ -8,6 +8,7 @@ from outils.common import CouchDB
from
outils.common
import
Verification
from
products.models
import
OFF
from
envelops.models
import
CagetteEnvelops
import
shifts.fonctions
import
sys
import
pytz
...
...
@@ -203,6 +204,7 @@ class CagetteMember(models.Model):
if
getattr
(
settings
,
'ALLOW_NON_MEMBER_TO_CONNECT'
,
False
)
is
False
:
cond
.
append
(
'|'
)
cond
.
append
([
'is_member'
,
'='
,
True
])
# TODO : consider replacing is_associated_people by suppleant_member_id to exclude mineurs rattachés
cond
.
append
([
'is_associated_people'
,
'='
,
True
])
fields
=
[
'name'
,
'email'
,
'birthdate_date'
,
'create_date'
,
'cooperative_state'
,
'is_associated_people'
,
'barcode_base'
]
...
...
@@ -212,6 +214,7 @@ class CagetteMember(models.Model):
if
(
res
and
len
(
res
)
>=
1
):
coop_id
=
None
hashed_password
=
None
# TODO : add comment to explain why there is a loop here
for
item
in
res
:
coop
=
item
if
'hashed_password'
in
item
:
...
...
@@ -219,6 +222,7 @@ class CagetteMember(models.Model):
if
item
[
"birthdate_date"
]
is
not
False
:
coop_birthdate
=
item
[
'birthdate_date'
]
coop_state
=
item
[
'cooperative_state'
]
# TODO : consider replacing is_associated_people check by suppleant_member_id to exclude mineurs rattachés
if
item
[
"is_associated_people"
]
==
True
:
coop_id
=
item
[
'id'
]
...
...
@@ -460,18 +464,12 @@ class CagetteMember(models.Model):
def
is_associated
(
id_parent
):
api
=
OdooAPI
()
cond
=
[[
'parent_id'
,
'='
,
int
(
id_parent
)]]
fields
=
[
'id'
,
'name'
,
'parent_id'
,
'birthdate_date'
]
fields
=
[
'id'
,
'name'
,
'parent_id'
,
'birthdate_date'
,
'suppleant_member_id'
]
res
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
,
10
,
0
,
'id DESC'
)
already_have_adult_associated
=
False
for
partner
in
res
:
birthdate
=
partner
[
'birthdate_date'
]
if
(
birthdate
):
today
=
date
.
today
()
date1
=
datetime
.
datetime
.
strptime
(
birthdate
,
"
%
Y-
%
m-
%
d"
)
age
=
today
.
year
-
date1
.
year
-
((
today
.
month
,
today
.
day
)
<
(
date1
.
month
,
date1
.
day
))
if
age
>
17
:
already_have_adult_associated
=
True
return
already_have_adult_associated
if
partner
[
'suppleant_member_id'
]:
return
True
return
False
@staticmethod
def
finalize_coop_creation
(
post_data
):
...
...
@@ -657,7 +655,8 @@ class CagetteMember(models.Model):
'city'
:
post_data
[
'city'
],
'phone'
:
format_phone_number
(
post_data
[
'mobile'
]),
# Because list view default show Phone and people mainly gives mobile
'barcode_rule_id'
:
settings
.
ASSOCIATE_BARCODE_RULE_ID
,
'parent_id'
:
post_data
[
'parent_id'
],
'parent_id'
:
post_data
[
'parent_id'
],
'suppleant_member_id'
:
partner_id
,
'is_associated_people'
:
True
,
'function'
:
function
}
...
...
@@ -901,6 +900,7 @@ class CagetteMember(models.Model):
cond
=
[[
'name'
,
'ilike'
,
str
(
key
)]]
cond
.
append
(
'|'
)
cond
.
append
([
'is_member'
,
'='
,
True
])
#TODO : replace is_associated_people check by suppleant_member_id check to exclude mineurs rattachés
if
search_type
!=
'members'
and
search_type
!=
'envelops'
:
cond
.
append
([
'is_associated_people'
,
'='
,
True
])
else
:
...
...
@@ -953,7 +953,7 @@ class CagetteMember(models.Model):
fields
=
fields
+
[
'shift_type'
,
'makeups_to_do'
,
'display_ftop_points'
,
'display_std_points'
,
'shift_type'
]
cond
.
append
([
'shift_type'
,
'='
,
'standard'
])
res
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
CagetteMembers
.
add_makeups_to_come_to_member_data
(
res
)
CagetteMembers
.
add_makeups_to_come_to_member_data
(
api
,
res
)
return
res
elif
search_type
==
"shift_template_data"
:
fields
=
CagetteMember
.
m_short_default_fields
...
...
@@ -1044,25 +1044,19 @@ class CagetteMember(models.Model):
res
=
{}
c
=
[[
"parent_id"
,
"="
,
self
.
id
]]
f
=
[
"id"
,
"name"
,
"barcode_base"
]
f
=
[
"id"
,
"name"
,
"barcode_base"
,
'suppleant_member_id'
]
res
=
self
.
o_api
.
search_read
(
'res.partner'
,
c
,
f
)
try
:
return
res
[
0
]
except
:
for
partner
in
res
:
if
partner
[
'suppleant_member_id'
]:
return
partner
return
None
def
update_member_makeups
(
self
,
member_data
):
api
=
OdooAPI
()
res
=
{}
# Prevent setting a negative number of makeups_to_do
# https://redmine.coopdev.fr/issues/6090
# This could happen when bdm has two screens open and clicks on minus btn on a coop line
# with exactly 1 makeup_to_do on both screens
makeups_to_do
=
max
(
0
,
int
(
member_data
[
"target_makeups_nb"
]))
f
=
{
'makeups_to_do'
:
makeups_to_do
}
makeups_to_do
=
int
(
member_data
[
"target_makeups_nb"
])
f
=
{
'makeups_to_do'
:
makeups_to_do
}
res_item
=
api
.
update
(
'res.partner'
,
[
self
.
id
],
f
)
res
=
{
'mid'
:
self
.
id
,
...
...
@@ -1164,6 +1158,12 @@ class CagetteMember(models.Model):
else
:
return
False
def
has_state_unsubscribed_gone_or_associated
(
self
):
c
=
[[
'id'
,
'='
,
self
.
id
]]
f
=
[
'cooperative_state'
]
state
=
self
.
o_api
.
search_read
(
"res.partner"
,
c
,
f
)[
0
][
"cooperative_state"
]
return
state
in
(
"unsubscribed"
,
"gone"
,
"associated"
)
class
CagetteMembers
(
models
.
Model
):
"""Class to manage operations on all members or part of them."""
...
...
@@ -1400,8 +1400,7 @@ class CagetteMembers(models.Model):
# 1 : fetching members with no makeups to do but with some makeups to come
# 2 : providing makeups to come to all members
cs
=
CagetteShift
()
makeups_to_come_per_partner
=
cs
.
get_partners_with_makeups_to_come
()
makeups_to_come_per_partner
=
shifts
.
fonctions
.
get_partners_with_makeups_to_come
(
api
)
# 1 : fetching members with no makeups to do but with some makeups to come
cond
=
[[
'makeups_to_do'
,
'='
,
0
],
[
'id'
,
'in'
,
list
(
makeups_to_come_per_partner
.
keys
())]]
...
...
@@ -1421,20 +1420,20 @@ class CagetteMembers(models.Model):
return
res
@staticmethod
def
add_makeups_to_come_to_member_data
(
res
):
def
add_makeups_to_come_to_member_data
(
api
,
res
):
if
res
:
cs
=
CagetteShift
()
for
idx
,
partner
in
enumerate
(
res
):
[
shift_data
,
is_ftop
]
=
cs
.
get_shift_partner
(
int
(
partner
[
'id'
]))
[
shift_data
,
is_ftop
]
=
shifts
.
fonctions
.
get_shift_partner
(
api
,
int
(
partner
[
'id'
]))
res
[
idx
][
'makeups_to_come'
]
=
sum
(
1
for
value
in
shift_data
if
value
[
'is_makeup'
])
@staticmethod
def
get_attached_members
():
api
=
OdooAPI
()
cond
=
[[
'is_associated_people'
,
'='
,
True
]]
fields
=
[
'id'
,
'name'
,
'parent_name'
]
cond
=
[[
'is_associated_people'
,
'='
,
True
]]
fields
=
[
'id'
,
'name'
,
'parent_name'
,
'suppleant_member_id'
]
res
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
return
res
# Exclude mineurs rattachés
return
[
x
for
x
in
res
if
res
[
'suppleant_member_id'
]]
class
CagetteUser
(
models
.
Model
):
...
...
@@ -1525,5 +1524,3 @@ class CagetteUser(models.Model):
res
[
'error'
]
=
str
(
e
)
return
res
\ No newline at end of file
from
shifts.models
import
CagetteShift
members_space/views.py
View file @
e5bff7b4
...
...
@@ -218,7 +218,7 @@ def home(request):
if
partnerData
[
'cooperative_state'
]
==
"unsubscribed"
:
coop_can_change_shift_template
=
False
if
getattr
(
settings
,
'ASSOCIATE_PEOPLE_CAN_CHANGE_SHIFT_TEMPLE_REGISTRATION'
,
False
)
is
False
:
if
partnerData
[
'
is_associated_people'
]
is
True
:
if
partnerData
[
'
suppleant_member_id'
]
:
coop_can_change_shift_template
=
False
context
=
{
'title'
:
'Espace Membres'
,
...
...
shifts/fonctions.py
View file @
e5bff7b4
import
datetime
,
pytz
tz
=
pytz
.
timezone
(
"Europe/Paris"
)
def
dateIsoUTC
(
myDate
):
tz
=
pytz
.
timezone
(
"Europe/Paris"
)
tDate
=
tz
.
localize
(
datetime
.
datetime
.
strptime
(
myDate
,
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
))
return
dDate
.
isoformat
()
return
tDate
.
isoformat
()
def
get_partners_with_makeups_to_come
(
api
):
"""Returns a dictionary with : keys = the partners ids having at least one makeup to come ; values = #makeups_to_come"""
fields
=
[
'partner_id'
]
cond
=
[[
'state'
,
'='
,
'open'
],
[
'date_begin'
,
'>'
,
datetime
.
datetime
.
now
()
.
isoformat
()],
[
'is_makeup'
,
'='
,
True
]]
shift_data
=
api
.
search_read
(
'shift.registration'
,
cond
,
fields
)
count_dic
=
{}
for
value
in
shift_data
:
if
value
[
'partner_id'
][
0
]
in
count_dic
:
count_dic
[
value
[
'partner_id'
][
0
]]
=
count_dic
[
value
[
'partner_id'
][
0
]]
+
1
else
:
count_dic
[
value
[
'partner_id'
][
0
]]
=
1
return
count_dic
def
get_shift_partner
(
api
,
id
,
start_date
=
None
,
end_date
=
None
):
"""Récupère les shift du membre"""
shifts
=
[]
is_ftop
=
False
not_before
=
datetime
.
datetime
.
now
()
.
isoformat
()
if
start_date
:
not_before
=
start_date
.
isoformat
()
fields
=
[
'date_begin'
,
'date_end'
,
'shift_id'
,
'shift_type'
,
'partner_id'
,
"id"
,
"associate_registered"
,
"is_makeup"
]
# res.partner
cond
=
[[
'partner_id.id'
,
'='
,
id
],
[
'state'
,
'='
,
'open'
],
[
'date_begin'
,
'>'
,
not_before
]]
if
end_date
:
cond
.
append
([
'date_begin'
,
'<'
,
end_date
.
isoformat
()])
shiftData
=
api
.
search_read
(
'shift.registration'
,
cond
,
fields
,
order
=
"date_begin ASC"
)
for
s
in
shiftData
:
if
not
(
'Equipe volante'
in
s
[
'shift_id'
][
1
]):
shifts
.
append
(
s
)
else
:
is_ftop
=
True
return
[
shifts
,
is_ftop
]
def
get_exempted_ids_from
(
api
,
partner_ids
):
cond
=
[[
'id'
,
'in'
,
partner_ids
],
[
'cooperative_state'
,
'in'
,
[
'exempted'
]]]
fields
=
[
'id'
]
return
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
\ No newline at end of file
shifts/models.py
View file @
e5bff7b4
This diff is collapsed.
Click to expand it.
shifts/views.py
View file @
e5bff7b4
...
...
@@ -4,16 +4,13 @@ from outils.common import Verification
from
shifts.models
import
CagetteShift
from
members.models
import
CagetteMember
import
shifts.fonctions
# working_state = ['up_to_date', 'alert', 'exempted', 'delay', 'suspended']
state_shift_allowed
=
[
"up_to_date"
,
"alert"
,
"delay"
]
tz
=
pytz
.
timezone
(
"Europe/Paris"
)
def
dateIsoUTC
(
myDate
):
tDate
=
tz
.
localize
(
datetime
.
datetime
.
strptime
(
myDate
,
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
))
return
tDate
.
isoformat
()
def
home
(
request
,
partner_id
,
hashed_date
):
import
hashlib
cs
=
CagetteShift
()
...
...
@@ -96,7 +93,7 @@ def _is_middled_filled_considered(reserved, max):
def
get_list_shift_calendar
(
request
,
partner_id
):
cs
=
CagetteShift
()
[
registerPartner
,
is_ftop
]
=
cs
.
get_shift_partner
(
partner_id
)
[
registerPartner
,
is_ftop
]
=
shifts
.
fonctions
.
get_shift_partner
(
cs
.
o_api
,
partner_id
)
use_new_members_space
=
getattr
(
settings
,
'USE_NEW_MEMBERS_SPACE'
,
False
)
remove_15_minutes_at_shift_end
=
getattr
(
settings
,
'REMOVE_15_MINUTES_AT_SHIFT_END'
,
True
)
...
...
@@ -132,12 +129,12 @@ def get_list_shift_calendar(request, partner_id):
event
[
"title"
]
=
title_prefix
+
str
(
value
[
'seats_reserved'
])
+
"/"
+
str
(
smax
)
event
[
"start"
]
=
dateIsoUTC
(
value
[
'date_begin_tz'
])
event
[
"start"
]
=
shifts
.
fonctions
.
dateIsoUTC
(
value
[
'date_begin_tz'
])
datetime_object
=
datetime
.
datetime
.
strptime
(
value
[
'date_end_tz'
],
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)
-
datetime
.
timedelta
(
minutes
=
15
)
if
remove_15_minutes_at_shift_end
is
True
:
datetime_object
-=
datetime
.
timedelta
(
minutes
=
15
)
event
[
"end"
]
=
dateIsoUTC
(
datetime_object
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
))
event
[
"end"
]
=
shifts
.
fonctions
.
dateIsoUTC
(
datetime_object
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
))
if
len
(
l
)
>
0
:
if
use_new_members_space
is
True
:
...
...
@@ -178,7 +175,7 @@ def get_list_shift_calendar(request, partner_id):
def
get_list_shift_partner
(
request
,
partner_id
):
cs
=
CagetteShift
()
[
shiftData
,
is_ftop
]
=
cs
.
get_shift_partner
(
partner_id
)
[
shiftData
,
is_ftop
]
=
shifts
.
fonctions
.
get_shift_partner
(
cs
.
o_api
,
partner_id
)
for
value
in
shiftData
:
value
[
'date_begin'
]
=
value
[
'date_begin'
]
+
"Z"
...
...
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