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
0d7c8c32
Commit
0d7c8c32
authored
Jan 18, 2023
by
François C.
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add app administation features
parent
b2704620
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
318 additions
and
18 deletions
+318
-18
models.py
administration/models.py
+69
-2
admin_common.css
administration/static/css/admin_common.css
+19
-0
admin_common.js
administration/static/js/admin_common.js
+22
-0
inventory_backups.js
administration/static/js/inventory_backups.js
+112
-0
master_admin.js
administration/static/js/master_admin.js
+3
-1
urls.py
administration/urls.py
+7
-3
views.py
administration/views.py
+45
-11
models.py
members/models.py
+3
-0
index.html
templates/admin/index.html
+5
-1
inventory_backups.html
templates/admin/inventory_backups.html
+33
-0
No files found.
administration/models.py
View file @
0d7c8c32
from
django.db
import
models
from
django.db
import
models
from
outils.common_imports
import
*
from
outils.common_imports
import
*
from
shelfs.models
import
Shelf
,
Shelfs
import
glob
import
glob
class
ThirdPartyAdmin
(
models
.
Model
):
class
ThirdPartyAdmin
(
models
.
Model
):
"""Class to manage third party and view logs"""
"""Class to manage third party and view logs"""
@staticmethod
@staticmethod
def
get_inventory_backups
():
content
=
[]
files
=
[]
for
file
in
glob
.
glob
(
"data/inventories_backup/*.json"
):
files
.
append
(
file
)
files
.
sort
()
if
len
(
files
)
>
0
:
shelfs_map
=
{}
for
shelf
in
Shelfs
.
get_all
(
'simple'
):
shelfs_map
[
str
(
shelf
[
'id'
])]
=
shelf
[
'name'
]
for
f
in
files
:
fn
=
f
.
split
(
'/'
)[
-
1
]
inv_file
=
fn
.
replace
(
".json"
,
""
)
(
timestamp
,
shelf_id
)
=
inv_file
.
split
(
'__'
)
(
date
,
hms
)
=
timestamp
.
split
(
'--'
)
hms
=
hms
.
replace
(
'-'
,
':'
)
content
.
append
({
'file'
:
fn
,
'date'
:
date
,
'hms'
:
hms
,
'shelf_id'
:
shelf_id
,
'shelf_name'
:
shelfs_map
[
str
(
shelf_id
)]
})
return
content
@staticmethod
def
merge_inventory_data
(
elts
):
result
=
{
'name'
:
''
,
'inventory_status'
:
''
,
'list_processed'
:
[],
'total_price'
:
0
}
names
=
[]
for
elt
in
elts
:
name
=
elt
[
'name'
]
if
elt
[
'inventory_status'
]
==
""
:
name
+=
" (Etape 1)"
else
:
name
+=
" (Etape 2)"
names
.
append
(
name
)
result
[
'list_processed'
]
+=
elt
[
'list_processed'
]
result
[
'name'
]
=
' // '
.
join
(
names
)
# Retrieve product data (price at date)
# and compute total purchase price
i
=
0
for
inv_line
in
result
[
'list_processed'
]:
line_price
=
round
(
inv_line
[
'standard_price'
]
*
inv_line
[
'qty'
],
2
)
result
[
'total_price'
]
+=
line_price
result
[
'list_processed'
][
i
][
'line_price'
]
=
line_price
i
+=
1
return
result
@staticmethod
def
get_inventory_backup
(
file_names
):
data
=
[]
result
=
{}
fn
=
file_names
.
split
(
'|-|'
)
try
:
for
file_name
in
fn
:
fpath
=
"data/inventories_backup/"
+
file_name
inventory_data
=
{}
with
open
(
fpath
)
as
json_file
:
inventory_data
=
json
.
load
(
json_file
)
data
.
append
(
inventory_data
)
result
=
ThirdPartyAdmin
.
merge_inventory_data
(
data
)
except
Exception
as
e
:
coop_logger
.
error
(
"get_inventory_backup :
%
s"
,
str
(
e
))
return
result
@staticmethod
def
get_django_logs
():
def
get_django_logs
():
content
=
[]
content
=
[]
for
file
in
glob
.
glob
(
"log/*.log"
):
for
file
in
glob
.
glob
(
"log/*.log"
):
with
open
(
file
)
as
f
:
with
open
(
file
)
as
f
:
content
.
append
({
'key'
:
file
,
'value'
:
f
.
readlines
()})
content
.
append
({
'key'
:
file
,
'value'
:
f
.
readlines
()})
return
content
return
content
\ No newline at end of file
administration/static/css/admin_common.css
View file @
0d7c8c32
.page_body
tr
:hover
{
background-color
:
#ffff99
;
}
.page_body
tr
.selected
{
background-color
:
#ff0099
;
}
#displayed_results
{
margin-top
:
25px
;
padding-top
:
25px
;
border-top
:
3px
dotted
grey
;
background-color
:
beige
;
}
.select_file_cb
{
z-index
:
2000000
;
}
\ No newline at end of file
administration/static/js/admin_common.js
View file @
0d7c8c32
...
@@ -90,6 +90,28 @@ var createTabs = async function(params) {
...
@@ -90,6 +90,28 @@ var createTabs = async function(params) {
return
result
;
return
result
;
}
}
var
showListInDatatable
=
function
(
parent_div
,
list_data
,
colums_def
,
row_click_handler
)
{
// Init table for items to process
const
d
=
new
Date
();
let
table
=
$
(
'<table>'
).
attr
(
'id'
,
d
.
getTime
())
$
(
parent_div
).
append
(
table
);
let
data_table
=
table
.
DataTable
({
data
:
list_data
,
columns
:
colums_def
,
paging
:
false
,
dom
:
'lrtip'
,
// Remove the search input from that table
language
:
{
url
:
'/static/js/datatables/french.json'
}
});
$
(
'#'
+
d
.
getTime
()
+
' tbody'
).
on
(
'click'
,
'td.as-row-clickable'
,
function
()
{
const
clicked
=
$
(
this
)
var
row
=
data_table
.
row
(
this
);
table
.
find
(
'tr'
).
removeClass
(
'selected'
);
clicked
.
closest
(
'tr'
).
addClass
(
'selected'
)
row_click_handler
(
row
.
data
())
});
return
data_table
;
}
$
(
'#back_to_admin_index'
).
on
(
'click'
,
function
()
{
$
(
'#back_to_admin_index'
).
on
(
'click'
,
function
()
{
const
to_remove
=
window
.
location
.
href
.
split
(
'/'
).
pop
();
const
to_remove
=
window
.
location
.
href
.
split
(
'/'
).
pop
();
const
new_url
=
window
.
location
.
href
.
replace
(
to_remove
,
""
);
const
new_url
=
window
.
location
.
href
.
replace
(
to_remove
,
""
);
...
...
administration/static/js/inventory_backups.js
0 → 100644
View file @
0d7c8c32
const
displayed_results
=
document
.
querySelector
(
'#displayed_results'
);
let
files_list_row_click_handler
=
function
(
data
)
{
load_content
(
'/administration/retrieve_inventory_backup/'
+
data
.
file
).
then
(
rep
=>
{
if
(
typeof
rep
.
content
!==
"undefined"
)
{
show_file_content
(
rep
.
content
);
}
else
{
alert
(
"La récupération du fichier n'a pas aboutie"
);
}
});
}
let
content_file_row_click_handler
=
function
(
data
)
{
}
let
show_file_content
=
function
(
data
)
{
let
title
=
'<h3>Saisie du rayon '
+
data
.
name
+
'</h3>'
,
info
=
$
(
'<p>'
).
addClass
(
'info'
);
$
(
displayed_results
).
empty
();
$
(
displayed_results
).
append
(
title
);
info
.
append
(
'Total HT : <b>'
+
data
.
total_price
+
' €</b>'
)
$
(
displayed_results
).
append
(
info
);
const
columns
=
[
{
data
:
"id"
,
visible
:
false
},
{
data
:
"barcode"
,
title
:
"Code-barre"
,
},
{
data
:
"name"
,
title
:
"Nom article"
,
},
{
data
:
"qty_available"
,
title
:
"Théorique"
,
},
{
data
:
"qty"
,
title
:
"Compté"
,
},
{
data
:
"standard_price"
,
title
:
"Achat HT"
,
},
{
data
:
"line_price"
,
title
:
"Total HT"
,
},
];
showListInDatatable
(
displayed_results
,
data
.
list_processed
,
columns
,
content_file_row_click_handler
);
};
let
get_selections_data
=
function
()
{
let
files
=
[];
$
(
'input.select_file_cb:checked'
).
each
(
function
(
i
,
elt
)
{
files
.
push
(
$
(
elt
).
val
())
});
files_list_row_click_handler
({
file
:
files
.
join
(
'|-|'
)})
}
let
show_files_list
=
function
(
params
)
{
const
columns
=
[
{
data
:
"file"
,
className
:
"dt-body-center"
,
orderable
:
false
,
render
:
function
(
data
)
{
return
`<input type="checkbox" class="select_file_cb" value="
${
data
}
">`
;
},
width
:
"4%"
},
{
data
:
"date"
,
title
:
"Jour"
,
className
:
"as-row-clickable"
},
{
data
:
"hms"
,
title
:
"HMS"
,
className
:
"as-row-clickable"
},
{
data
:
"shelf_name"
,
title
:
"Rayon"
,
className
:
"as-row-clickable"
},
];
showListInDatatable
(
params
.
parentElt
,
params
.
data
,
columns
,
files_list_row_click_handler
);
$
(
document
).
off
(
'click.select_file'
);
$
(
document
).
on
(
'click.select_file'
,
'.select_file_cb'
,
function
(
event
){
event
.
stopPropagation
();
get_selections_data
();
});
};
// Chargement des données et traitement
load_content
(
'/administration/retrieve_inventory_backups'
).
then
(
rep
=>
{
if
(
typeof
rep
.
content
!==
"undefined"
)
{
const
params
=
{
parentElt
:
document
.
querySelector
(
'[class="page_body"]'
),
data
:
rep
.
content
};
show_files_list
(
params
);
}
else
{
alert
(
"La récupération des fichiers n'a pas aboutie"
);
}
});
\ No newline at end of file
administration/static/js/master_admin.js
View file @
0d7c8c32
...
@@ -7,7 +7,9 @@ $(document).ready(function() {
...
@@ -7,7 +7,9 @@ $(document).ready(function() {
let
location
=
window
.
location
.
href
.
replace
(
/
\/
$/
,
''
);
let
location
=
window
.
location
.
href
.
replace
(
/
\/
$/
,
''
);
$
(
'.management_type_button'
).
on
(
'click'
,
function
()
{
$
(
'.management_type_button'
).
on
(
'click'
,
function
()
{
if
(
this
.
id
==
'manage_django_logs'
)
{
if
(
this
.
id
==
'manage_inventory_data'
)
{
window
.
location
.
assign
(
location
+
"/inventory_backups"
);
}
else
if
(
this
.
id
==
'manage_django_logs'
)
{
window
.
location
.
assign
(
location
+
"/django_logs"
);
window
.
location
.
assign
(
location
+
"/django_logs"
);
}
else
if
(
this
.
id
==
'manage_odoo_logs'
)
{
}
else
if
(
this
.
id
==
'manage_odoo_logs'
)
{
window
.
location
.
assign
(
location
+
"/odoo_logs"
);
window
.
location
.
assign
(
location
+
"/odoo_logs"
);
...
...
administration/urls.py
View file @
0d7c8c32
...
@@ -6,7 +6,10 @@ from . import views
...
@@ -6,7 +6,10 @@ from . import views
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^$'
,
views
.
index
,
name
=
'index'
),
url
(
r'^$'
,
views
.
index
,
name
=
'index'
),
url
(
r'^django_logs$'
,
views
.
django_logs
,
name
=
'index'
),
url
(
r'^inventory_backups$'
,
views
.
inventory_backups
),
url
(
r'^odoo_logs$'
,
views
.
odoo_logs
,
name
=
'index'
),
url
(
r'^django_logs$'
,
views
.
django_logs
),
url
(
r'^retrieve_django_logs$'
,
views
.
retrieve_django_logs
,
name
=
'index'
),
url
(
r'^odoo_logs$'
,
views
.
odoo_logs
),
url
(
r'^retrieve_inventory_backups$'
,
views
.
retrieve_inventory_backups
),
url
(
r'^retrieve_inventory_backup/(.*)'
,
views
.
retrieve_inventory_backup
),
url
(
r'^retrieve_django_logs$'
,
views
.
retrieve_django_logs
),
]
]
\ No newline at end of file
administration/views.py
View file @
0d7c8c32
...
@@ -22,28 +22,61 @@ def index(request):
...
@@ -22,28 +22,61 @@ def index(request):
return
HttpResponse
(
template
.
render
(
context
,
request
))
return
HttpResponse
(
template
.
render
(
context
,
request
))
def
inventory_backups
(
request
):
"""Manage inventory backups."""
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
template
=
loader
.
get_template
(
'admin/inventory_backups.html'
)
context
=
{
'title'
:
"Sauvegardes saisies d'inventaire"
,
}
response
=
HttpResponse
(
template
.
render
(
context
,
request
))
else
:
response
=
HttpResponse
(
'Not allowed'
,
status
=
403
)
return
response
def
django_logs
(
request
):
def
django_logs
(
request
):
""" Administration des créneaux des membres """
""" Administration des créneaux des membres """
template
=
loader
.
get_template
(
'admin/django_logs.html'
)
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
template
=
loader
.
get_template
(
'admin/django_logs.html'
)
context
=
{
'title'
:
'Logs Django'
,
context
=
{
}
'title'
:
'Logs Django'
,
return
HttpResponse
(
template
.
render
(
context
,
request
))
}
response
=
HttpResponse
(
template
.
render
(
context
,
request
))
else
:
response
=
HttpResponse
(
'Not allowed'
,
status
=
403
)
return
response
def
odoo_logs
(
request
):
def
odoo_logs
(
request
):
""" Administration des créneaux des membres """
""" Administration des créneaux des membres """
template
=
loader
.
get_template
(
'admin/odoo_logs.html'
)
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
template
=
loader
.
get_template
(
'admin/odoo_logs.html'
)
context
=
{
context
=
{
'title'
:
'Logs Odoo'
,
'title'
:
'Logs Odoo'
,
}
}
return
HttpResponse
(
template
.
render
(
context
,
request
))
response
=
HttpResponse
(
template
.
render
(
context
,
request
))
else
:
response
=
HttpResponse
(
'Not allowed'
,
status
=
403
)
def
retrieve_django_logs
(
request
):
def
retrieve_django_logs
(
request
):
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
response
=
JsonResponse
({
'content'
:
ThirdPartyAdmin
.
get_django_logs
()})
response
=
JsonResponse
({
'content'
:
ThirdPartyAdmin
.
get_django_logs
()})
else
:
else
:
response
=
JsonResponse
({},
status
=
403
)
response
=
JsonResponse
({},
status
=
403
)
return
response
def
retrieve_inventory_backups
(
request
):
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
response
=
JsonResponse
({
'content'
:
ThirdPartyAdmin
.
get_inventory_backups
()})
else
:
response
=
JsonResponse
({},
status
=
403
)
return
response
def
retrieve_inventory_backup
(
request
,
files
):
if
CagetteUser
.
are_credentials_ok
(
request
)
and
CagetteUser
.
isAllowedToAdmin
(
request
):
response
=
JsonResponse
({
'content'
:
ThirdPartyAdmin
.
get_inventory_backup
(
files
)})
else
:
response
=
JsonResponse
({},
status
=
403
)
return
response
return
response
\ No newline at end of file
members/models.py
View file @
0d7c8c32
...
@@ -1366,6 +1366,9 @@ class CagetteUser(models.Model):
...
@@ -1366,6 +1366,9 @@ class CagetteUser(models.Model):
@staticmethod
@staticmethod
def
isAllowedToAdmin
(
request
):
def
isAllowedToAdmin
(
request
):
"""Need to create an odoo Group called 'django admin'."""
"""Need to create an odoo Group called 'django admin'."""
"""
In Odoo, create a group named 'django admin' and add Odoo user(s)
"""
answer
=
False
answer
=
False
groups
=
CagetteUser
.
get_groups
(
request
)
groups
=
CagetteUser
.
get_groups
(
request
)
...
...
templates/admin/index.html
View file @
0d7c8c32
...
@@ -18,11 +18,15 @@
...
@@ -18,11 +18,15 @@
{% if is_connected %}
{% if is_connected %}
{% if is_admin %}
{% if is_admin %}
<div
class=
"management_type_buttons txtcenter"
>
<div
class=
"management_type_buttons txtcenter"
>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_inventory_data"
>
Sauvegardes saisies d'inventaire
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
</button><br>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_django_logs"
>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_django_logs"
>
Logs Django
Logs Django
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
</button><br>
</button><br>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_odoo_logs"
>
<button
type=
"button"
class=
"btn--primary management_type_button"
id=
"manage_odoo_logs"
disabled
>
Logs Odoo
Logs Odoo
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
<span
class=
"management_type_button_icons"
><i
class=
"fas fa-arrow-right"
></i></span>
</button><br>
</button><br>
...
...
templates/admin/inventory_backups.html
0 → 100644
View file @
0d7c8c32
{% extends "base.html" %}
{% load static %}
{% block additionnal_css %}
<link
rel=
"stylesheet"
href=
"{% static 'css/datatables/jquery.dataTables.css' %}"
>
<link
rel=
"stylesheet"
href=
"{% static 'css/diasg_tabs.css' %}"
>
<link
rel=
"stylesheet"
href=
"{% static 'css/admin_common.css' %}"
>
{% endblock %}
{% block additionnal_scripts %}
<script
type=
"text/javascript"
src=
"{% static 'js/download.js' %}"
></script>
<script
type=
"text/javascript"
src=
"{% static 'js/datatables/jquery.dataTables.min.js' %}"
></script>
<script
type=
"text/javascript"
src=
"{% static 'js/datatables/dataTables.plugins.js' %}"
></script>
{% endblock %}
{% block content %}
<div
id=
"admin_connexion_button"
>
{% include "common/conn_admin.html" %}
</div>
<div
class=
"page_body"
>
<div
id=
"back_to_admin_index"
>
<button
type=
"button"
class=
"btn--danger"
><i
class=
"fas fa-arrow-left"
></i>
Retour
</button>
</div>
<h2>
Sauvegardes des saisies d'inventaires
</h2>
</div>
<div
id=
"displayed_results"
>
</div>
<div>
<script
src=
'{% static "js/all_common.js" %}?v='
></script>
<script
src=
'{% static "js/admin_common.js" %}?v='
></script>
<script
src=
'{% static "js/inventory_backups.js" %}?v='
></script>
{% endblock %}
\ No newline at end of file
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