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
76b93ae3
Commit
76b93ae3
authored
Feb 11, 2022
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add payments & shares in envelops
parent
6931eb3a
Pipeline
#1789
passed with stage
in 1 minute 37 seconds
Changes
10
Pipelines
1
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
199 additions
and
19 deletions
+199
-19
models.py
envelops/models.py
+22
-3
envelops.css
envelops/static/css/envelops.css
+68
-4
envelops.js
envelops/static/js/envelops.js
+0
-0
views.py
envelops/views.py
+4
-1
models.py
members/models.py
+9
-1
urls.py
members/urls.py
+1
-0
views.py
members/views.py
+24
-2
scripts_settings_example.py
outils/scripts/scripts_settings_example.py
+1
-1
all_common.js
outils/static/js/all_common.js
+2
-2
index.html
templates/envelops/index.html
+68
-5
No files found.
envelops/models.py
View file @
76b93ae3
...
@@ -43,13 +43,32 @@ class CagetteEnvelops(models.Model):
...
@@ -43,13 +43,32 @@ class CagetteEnvelops(models.Model):
try
:
try
:
# Get invoice
# Get invoice
cond
=
[[
'partner_id'
,
'='
,
data
[
'partner_id'
]]]
# Get specific invoice if id is given
if
'invoice_id'
in
data
:
cond
=
[[
'id'
,
'='
,
data
[
'invoice_id'
]],
[
"number"
,
"!="
,
False
]]
else
:
cond
=
[[
'partner_id'
,
'='
,
data
[
'partner_id'
]],
[
"number"
,
"!="
,
False
]]
fields
=
[
'id'
,
'name'
,
'number'
,
'partner_id'
,
'residual_signed'
]
fields
=
[
'id'
,
'name'
,
'number'
,
'partner_id'
,
'residual_signed'
]
invoice_res
=
self
.
o_api
.
search_read
(
'account.invoice'
,
cond
,
fields
)
invoice_res
=
self
.
o_api
.
search_read
(
'account.invoice'
,
cond
,
fields
)
# Check if invoice exists
# Check if invoice exists
if
len
(
invoice_res
)
>
0
:
if
len
(
invoice_res
)
>
0
:
invoice
=
invoice_res
[
0
]
invoice
=
None
# Get first invoice for which amount being paid <= amount left to pay in invoice
for
invoice_item
in
invoice_res
:
if
int
(
float
(
data
[
'amount'
])
*
100
)
<=
int
(
float
(
invoice_item
[
'residual_signed'
])
*
100
):
invoice
=
invoice_ite
if
invoice
is
None
:
res
[
'error'
]
=
'The amount is too high for the invoices found for this partner.'
try
:
# Got an error while logging...
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
data
))
except
Exception
as
e
:
print
(
str
(
e
))
return
res
else
:
else
:
res
[
'error'
]
=
'No invoice found for this partner, can
\'
t create payment.'
res
[
'error'
]
=
'No invoice found for this partner, can
\'
t create payment.'
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
data
))
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
data
))
...
@@ -79,6 +98,7 @@ class CagetteEnvelops(models.Model):
...
@@ -79,6 +98,7 @@ class CagetteEnvelops(models.Model):
except
Exception
as
e
:
except
Exception
as
e
:
res
[
'error'
]
=
repr
(
e
)
res
[
'error'
]
=
repr
(
e
)
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
args
))
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
args
))
# Exception rises when odoo method returns nothing
# Exception rises when odoo method returns nothing
marshal_none_error
=
'cannot marshal None unless allow_none is enabled'
marshal_none_error
=
'cannot marshal None unless allow_none is enabled'
try
:
try
:
...
@@ -102,7 +122,6 @@ class CagetteEnvelops(models.Model):
...
@@ -102,7 +122,6 @@ class CagetteEnvelops(models.Model):
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
data
))
coop_logger
.
error
(
res
[
'error'
]
+
' :
%
s'
,
str
(
data
))
if
not
(
'error'
in
res
):
if
not
(
'error'
in
res
):
res
[
'done'
]
=
True
res
[
'done'
]
=
True
res
[
'payment_id'
]
=
payment_id
res
[
'payment_id'
]
=
payment_id
...
...
envelops/static/css/envelops.css
View file @
76b93ae3
...
@@ -2,6 +2,12 @@
...
@@ -2,6 +2,12 @@
margin-top
:
15px
;
margin-top
:
15px
;
}
}
#admin_connexion_button
{
position
:
absolute
;
top
:
5px
;
right
:
5px
;
}
.envelop_section
{
.envelop_section
{
margin-bottom
:
10px
;
margin-bottom
:
10px
;
}
}
...
@@ -10,16 +16,21 @@
...
@@ -10,16 +16,21 @@
display
:
none
;
display
:
none
;
cursor
:
pointer
;
cursor
:
pointer
;
margin-bottom
:
15px
;
margin-bottom
:
15px
;
width
:
25%
;
}
}
#cash_envelops
,
#ch_envelops
,
#archive_cash_envelops
,
#archive_ch_envelops
{
#cash_envelops
,
#ch_envelops
,
#archive_cash_envelops
,
#archive_ch_envelops
{
margin-top
:
30px
;
margin-top
:
30px
;
}
}
.
update_envelop_button
,
.
delete_envelop_button
,
.envelop_comment
{
.delete_envelop_button
,
.envelop_comment
{
margin
:
0
0
15px
15px
;
margin
:
0
0
15px
15px
;
}
}
.update_envelop_button
,
.add_to_envelop_button
{
margin
:
0
0
15px
10px
;
}
.envelop_content_list
{
.envelop_content_list
{
margin
:
20px
0
15px
0
;
margin
:
20px
0
15px
0
;
}
}
...
@@ -53,18 +64,18 @@
...
@@ -53,18 +64,18 @@
flex
:
50%
1
0
;
flex
:
50%
1
0
;
}
}
.line_partner_name_container
{
.
update_envelop_line
.
line_partner_name_container
{
display
:
flex
;
display
:
flex
;
justify-content
:
flex-start
;
justify-content
:
flex-start
;
align-items
:
center
;
align-items
:
center
;
}
}
.line_partner_name
{
.
update_envelop_line
.
line_partner_name
{
text-align
:
left
;
text-align
:
left
;
padding
:
0
5px
;
padding
:
0
5px
;
}
}
.line_partner_input_container
{
.
update_envelop_line
.
line_partner_input_container
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
}
}
...
@@ -80,6 +91,59 @@
...
@@ -80,6 +91,59 @@
margin-bottom
:
20px
;
margin-bottom
:
20px
;
}
}
/* Add payments to envelop modal */
.search_member_area
{
margin
:
20px
0
;
}
.search_member_results_area
{
margin
:
20px
0
;
}
.add_to_envelop_lines_area
{
margin
:
20px
0
;
}
.add_to_envelop_lines
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
margin
:
10px
0
;
}
.add_to_envelop_line
{
display
:
flex
;
justify-content
:
center
;
margin
:
10px
0
;
}
.add_to_envelop_line
.partner_name_container
{
display
:
flex
;
justify-content
:
flex-start
;
align-items
:
center
;
}
.add_to_envelop_line
.partner_input_container
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-start
;
margin-left
:
10px
;
width
:
300px
;
}
.line_partner_amount_error
{
display
:
none
;
color
:
#d9534f
;
font-style
:
italic
;
}
.confirm_add_payment_details
{
font-weight
:
bold
;
margin
:
0
3px
;
}
/* Accordion style */
/* Accordion style */
/* Style the buttons that are used to open and close the accordion panel */
/* Style the buttons that are used to open and close the accordion panel */
.accordion
{
.accordion
{
...
...
envelops/static/js/envelops.js
View file @
76b93ae3
This diff is collapsed.
Click to expand it.
envelops/views.py
View file @
76b93ae3
...
@@ -40,6 +40,9 @@ def archive_envelop(request):
...
@@ -40,6 +40,9 @@ def archive_envelop(request):
'type'
:
envelop
[
'type'
]
'type'
:
envelop
[
'type'
]
}
}
if
'invoice_id'
in
envelop
[
'envelop_content'
][
partner_id
]:
data
[
'invoice_id'
]
=
int
(
envelop
[
'envelop_content'
][
partner_id
][
'invoice_id'
])
res
=
m
.
save_payment
(
data
)
res
=
m
.
save_payment
(
data
)
except
Exception
as
e
:
except
Exception
as
e
:
res
=
{
res
=
{
...
@@ -75,7 +78,7 @@ def archive_envelop(request):
...
@@ -75,7 +78,7 @@ def archive_envelop(request):
coop_logger
.
error
(
"Cannot attach payment error message to member :
%
s"
,
str
(
e
))
coop_logger
.
error
(
"Cannot attach payment error message to member :
%
s"
,
str
(
e
))
try
:
try
:
# archive envelop
from
couchdb
# archive envelop
in
couchdb
res_envelop
=
m
.
archive_envelop
(
envelop
)
res_envelop
=
m
.
archive_envelop
(
envelop
)
except
Exception
as
e
:
except
Exception
as
e
:
res_envelop
=
"error"
res_envelop
=
"error"
...
...
members/models.py
View file @
76b93ae3
...
@@ -26,6 +26,9 @@ class CagetteMember(models.Model):
...
@@ -26,6 +26,9 @@ class CagetteMember(models.Model):
'display_ftop_points'
,
'display_std_points'
,
'display_ftop_points'
,
'display_std_points'
,
'is_exempted'
,
'cooperative_state'
,
'date_alert_stop'
]
'is_exempted'
,
'cooperative_state'
,
'date_alert_stop'
]
m_shoft_default_fields
=
[
'name'
,
'barcode_base'
,
'total_partner_owned_share'
,
'amount_subscription'
]
def
__init__
(
self
,
id
):
def
__init__
(
self
,
id
):
"""Init with odoo id."""
"""Init with odoo id."""
self
.
id
=
int
(
id
)
self
.
id
=
int
(
id
)
...
@@ -718,7 +721,7 @@ class CagetteMember(models.Model):
...
@@ -718,7 +721,7 @@ class CagetteMember(models.Model):
return
m_list
return
m_list
@staticmethod
@staticmethod
def
search
(
k_type
,
key
,
shift_id
=
None
):
def
search
(
k_type
,
key
,
shift_id
=
None
,
search_type
=
"full"
):
"""Search member according 3 types of key."""
"""Search member according 3 types of key."""
api
=
OdooAPI
()
api
=
OdooAPI
()
if
k_type
==
'id'
:
if
k_type
==
'id'
:
...
@@ -733,6 +736,7 @@ class CagetteMember(models.Model):
...
@@ -733,6 +736,7 @@ class CagetteMember(models.Model):
cond
.
append
([
'is_member'
,
'='
,
True
])
cond
.
append
([
'is_member'
,
'='
,
True
])
cond
.
append
([
'is_associated_people'
,
'='
,
True
])
cond
.
append
([
'is_associated_people'
,
'='
,
True
])
# cond.append(['cooperative_state', '!=', 'unsubscribed'])
# cond.append(['cooperative_state', '!=', 'unsubscribed'])
if
search_type
==
"full"
:
fields
=
CagetteMember
.
m_default_fields
fields
=
CagetteMember
.
m_default_fields
if
not
shift_id
is
None
:
if
not
shift_id
is
None
:
CagetteMember
.
m_default_fields
.
append
(
'tmpl_reg_line_ids'
)
CagetteMember
.
m_default_fields
.
append
(
'tmpl_reg_line_ids'
)
...
@@ -771,6 +775,10 @@ class CagetteMember(models.Model):
...
@@ -771,6 +775,10 @@ class CagetteMember(models.Model):
members
.
append
(
m
)
members
.
append
(
m
)
return
CagetteMember
.
add_next_shifts_to_members
(
members
)
return
CagetteMember
.
add_next_shifts_to_members
(
members
)
else
:
fields
=
CagetteMember
.
m_shoft_default_fields
res
=
api
.
search_read
(
'res.partner'
,
cond
,
fields
)
return
res
@staticmethod
@staticmethod
def
remove_data_from_CouchDB
(
request
):
def
remove_data_from_CouchDB
(
request
):
...
...
members/urls.py
View file @
76b93ae3
...
@@ -35,6 +35,7 @@ urlpatterns = [
...
@@ -35,6 +35,7 @@ urlpatterns = [
url
(
r'^menu/$'
,
views
.
menu
),
url
(
r'^menu/$'
,
views
.
menu
),
url
(
r'^verify_final_state$'
,
views
.
verify_final_state
),
url
(
r'^verify_final_state$'
,
views
.
verify_final_state
),
url
(
r'^update_couchdb_barcodes$'
,
views
.
update_couchdb_barcodes
),
url
(
r'^update_couchdb_barcodes$'
,
views
.
update_couchdb_barcodes
),
url
(
r'^add_shares_to_member$'
,
views
.
add_shares_to_member
),
# Borne accueil
# Borne accueil
url
(
r'^search/([^\/.]+)/?([0-9]*)'
,
views
.
search
),
url
(
r'^search/([^\/.]+)/?([0-9]*)'
,
views
.
search
),
url
(
r'^save_photo/([0-9]+)$'
,
views
.
save_photo
,
name
=
'save_photo'
),
url
(
r'^save_photo/([0-9]+)$'
,
views
.
save_photo
,
name
=
'save_photo'
),
...
...
members/views.py
View file @
76b93ae3
...
@@ -8,7 +8,7 @@ from members.models import CagetteMembers
...
@@ -8,7 +8,7 @@ from members.models import CagetteMembers
from
members.models
import
CagetteServices
from
members.models
import
CagetteServices
from
outils.forms
import
GenericExportMonthForm
from
outils.forms
import
GenericExportMonthForm
import
datetime
default_fields
=
[
'name'
,
default_fields
=
[
'name'
,
'image_medium'
]
'image_medium'
]
...
@@ -237,6 +237,8 @@ def update_couchdb_barcodes(request):
...
@@ -237,6 +237,8 @@ def update_couchdb_barcodes(request):
def
search
(
request
,
needle
,
shift_id
):
def
search
(
request
,
needle
,
shift_id
):
"""Search member has been requested."""
"""Search member has been requested."""
search_type
=
request
.
GET
.
get
(
'search_type'
,
''
)
try
:
try
:
key
=
int
(
needle
)
key
=
int
(
needle
)
k_type
=
'barcode_base'
k_type
=
'barcode_base'
...
@@ -247,7 +249,7 @@ def search(request, needle, shift_id):
...
@@ -247,7 +249,7 @@ def search(request, needle, shift_id):
key
=
needle
key
=
needle
k_type
=
'name'
k_type
=
'name'
res
=
CagetteMember
.
search
(
k_type
,
key
,
shift_id
)
res
=
CagetteMember
.
search
(
k_type
,
key
,
shift_id
,
search_type
)
return
JsonResponse
({
'res'
:
res
})
return
JsonResponse
({
'res'
:
res
})
...
@@ -391,6 +393,26 @@ def panel_get_purchases(request):
...
@@ -391,6 +393,26 @@ def panel_get_purchases(request):
response
=
HttpResponse
(
message
)
response
=
HttpResponse
(
message
)
return
response
return
response
def
add_shares_to_member
(
request
):
res
=
{}
is_connected_user
=
CagetteUser
.
are_credentials_ok
(
request
)
if
is_connected_user
is
True
:
try
:
data
=
json
.
loads
(
request
.
body
.
decode
())
partner_id
=
int
(
data
[
"partner_id"
])
amount
=
int
(
data
[
"amount"
])
except
Exception
as
e
:
res
[
'error'
]
=
"Wrong params"
return
JsonResponse
(
res
,
safe
=
False
,
status
=
400
)
m
=
CagetteMember
(
partner_id
)
today
=
datetime
.
date
.
today
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
res
=
m
.
create_capital_subscription_invoice
(
amount
,
today
)
return
JsonResponse
(
res
,
safe
=
False
)
else
:
res
[
'error'
]
=
"Forbidden"
return
JsonResponse
(
res
,
safe
=
False
,
status
=
403
)
# # # BDM # # #
# # # BDM # # #
def
save_partner_info
(
request
):
def
save_partner_info
(
request
):
...
...
outils/scripts/scripts_settings_example.py
View file @
76b93ae3
SECRET_KEY
=
'Mettre_plein_de_caracteres_aleatoires_iezezezeezezci'
SECRET_KEY
=
'Mettre_plein_de_caracteres_aleatoires_iezezezeezezci'
ODOO
=
{
ODOO
=
{
'url'
:
'http://127.0.0.1:8069'
'url'
:
'http://127.0.0.1:8069'
,
'user'
:
'api'
,
'user'
:
'api'
,
'passwd'
:
'xxxxxxxxxxxx'
,
'passwd'
:
'xxxxxxxxxxxx'
,
'db'
:
'bd_test'
,
'db'
:
'bd_test'
,
...
...
outils/static/js/all_common.js
View file @
76b93ae3
...
@@ -175,8 +175,8 @@ String.prototype.pad = function(String, len) {
...
@@ -175,8 +175,8 @@ String.prototype.pad = function(String, len) {
var
btns
=
$
(
'<div/>'
).
addClass
(
'btns'
);
var
btns
=
$
(
'<div/>'
).
addClass
(
'btns'
);
var
btn_ok
=
$
(
'<button/>'
).
addClass
(
'btn--success'
);
var
btn_ok
=
$
(
'<button/>'
).
addClass
(
'btn--success
btn-modal-ok
'
);
var
btn_nok
=
$
(
'<button/>'
).
addClass
(
'btn--danger'
)
var
btn_nok
=
$
(
'<button/>'
).
addClass
(
'btn--danger
btn-modal-nok
'
)
.
attr
(
'id'
,
'modal_closebtn_bottom'
)
.
attr
(
'id'
,
'modal_closebtn_bottom'
)
.
text
(
'Fermer'
);
.
text
(
'Fermer'
);
...
...
templates/envelops/index.html
View file @
76b93ae3
...
@@ -9,9 +9,11 @@
...
@@ -9,9 +9,11 @@
{% endblock %}
{% endblock %}
{% block content %}
{% block content %}
{%if must_identify %}
<div id="
admin_connexion_button
"
>
{%if must_identify %}
{% include "common/conn_admin.html" %}
{% include "common/conn_admin.html" %}
{%
endif
%}
{%endif%}
</div>
<div
id=
"envelop_cashing_error"
class=
"alert--danger clearfix custom_alert"
onClick=
"toggle_error_alert()"
>
<div
id=
"envelop_cashing_error"
class=
"alert--danger clearfix custom_alert"
onClick=
"toggle_error_alert()"
>
<div
style=
"width: 90%"
class=
"fl txtleft"
id=
"error_alert_txt"
></div>
<div
style=
"width: 90%"
class=
"fl txtleft"
id=
"error_alert_txt"
></div>
<div
style=
"width: 10%"
class=
"fr txtright"
><i
class=
"fas fa-times"
></i></div>
<div
style=
"width: 10%"
class=
"fr txtright"
><i
class=
"fas fa-times"
></i></div>
...
@@ -80,13 +82,74 @@
...
@@ -80,13 +82,74 @@
<div
class=
"deleted_line_through"
></div>
<div
class=
"deleted_line_through"
></div>
</div>
</div>
</div>
</div>
<div
id=
"modal_add_to_envelop"
>
<div
class=
"modal_add_to_envelop_content"
>
<h3>
Ajouter un paiement ou des parts sociales
</h3>
<h4><i
class=
"envelop_name"
></i></h4>
<hr>
<div
class=
"search_member_area"
>
<h4>
Rechercher un membre
</h4>
<form
class=
"search_member_form"
action=
"javascript:;"
method=
"post"
>
<input
type=
"text"
class=
"search_member_input"
value=
""
placeholder=
"Nom ou numéro du coop..."
required
>
<button
type=
"submit"
class=
"btn--primary"
class=
"search_member_button"
>
Recherche
</button>
</form>
</div>
<div
class=
"search_member_results_area"
style=
"display:none;"
>
<div
class=
"search_results_text"
>
<p><i>
Choisissez parmi les membres trouvés :
</i></p>
</div>
<div
class=
"search_member_results"
></div>
</div>
<div
class=
"add_to_envelop_lines_area"
style=
"display:none;"
>
<div
class=
"add_to_envelop_lines"
>
</div>
<div
class=
"validation_buttons"
>
<button
class=
"btn--primary add_payment_button"
>
Ajouter le paiement à l'enveloppe
</button>
<button
class=
"btn--primary add_shares_button"
>
Ajouter des parts sociales
</button>
</div>
</div>
</div>
</div>
<div
id=
"add_to_envelop_line_template"
>
<div
class=
"add_to_envelop_line"
>
<div
class=
"partner_name_container"
>
<span
class=
"line_partner_name"
></span>
</div>
<div
class=
"partner_input_container"
>
<input
type=
"text"
class=
"line_partner_amount"
placeholder=
"Montant"
>
<div
class=
"line_partner_amount_error"
>
Le montant doit être un nombre entier.
</div>
</div>
</div>
</div>
<div
id=
"modal_confirm_add_payment"
>
<p>
Vous vous apprêtez à ajouter un paiement de
<span
class=
"confirm_add_payment_details amount"
></span>
€
du membre
<span
class=
"confirm_add_payment_details member"
></span>
à l'enveloppe
<span
class=
"confirm_add_payment_details envelop"
></span>
.
</p>
<p><i>
<i
class=
"fas fa-exclamation-triangle"
></i>
Avertissement si ce.tte membre a plusieurs factures d'ouvertes.
<br/>
Au moment de l'encaissement de l'enveloppe, ce paiement sera lié à la plus vieille facture ouverte de ce membre.
</i></p>
</div>
<div
id=
"modal_confirm_add_shares"
>
<p>
Vous vous apprêtez à ajouter pour
<span
class=
"confirm_add_payment_details amount"
></span>
€ de parts sociales
au membre
<span
class=
"confirm_add_payment_details member"
></span>
.
</p>
<p>
Le paiement sera ajouté à l'enveloppe
<span
class=
"confirm_add_payment_details envelop"
></span>
.
</p>
</div>
</div>
</div>
<script
src=
"{% static "
js
/
pouchdb
.
min
.
js
"
%}"
></script>
<script
src=
"{% static "
js
/
pouchdb
.
min
.
js
"
%}"
></script>
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
{
%
if
must_identify
%
}
var
must_identify
=
'{{must_identify}}'
;
var
must_identify
=
true
{
%
endif
%
}
var
couchdb_dbname
=
'{{db}}'
;
var
couchdb_dbname
=
'{{db}}'
;
var
couchdb_server
=
'{{couchdb_server}}'
+
couchdb_dbname
;
var
couchdb_server
=
'{{couchdb_server}}'
+
couchdb_dbname
;
var
dbc
=
new
PouchDB
(
couchdb_dbname
);
var
dbc
=
new
PouchDB
(
couchdb_dbname
);
...
...
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