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
261
Issues
261
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Paul
third-party
Commits
a15908ef
Commit
a15908ef
authored
Jun 29, 2021
by
Damien Moulard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
create product orders in odoo
parent
6a661024
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
278 additions
and
21 deletions
+278
-21
models.py
orders/models.py
+75
-0
oders_helper_style.css
orders/static/css/oders_helper_style.css
+73
-5
orders_helper.js
orders/static/js/orders_helper.js
+0
-0
urls.py
orders/urls.py
+2
-0
views.py
orders/views.py
+45
-2
models.py
products/models.py
+19
-10
helper.html
templates/orders/helper.html
+64
-4
No files found.
orders/models.py
View file @
a15908ef
...
...
@@ -222,6 +222,81 @@ class Order(models.Model):
labels_data
[
'total'
]
+=
l
[
'product_qty'
]
return
labels_data
def
get_order_attachment_id
(
self
):
res
=
{}
f
=
[
"id"
]
c
=
[[
'res_model'
,
'='
,
'purchase.order'
],
[
'res_id'
,
'='
,
self
.
id
],
[
'type'
,
'in'
,
[
'binary'
,
'url'
]]]
try
:
attachment
=
self
.
o_api
.
search_read
(
'ir.attachment'
,
c
,
f
)
res
=
attachment
[
0
]
except
Exception
as
e
:
res
[
"id_po"
]
=
self
.
id
res
[
"error"
]
=
str
(
e
)
return
res
@staticmethod
def
create
(
supplier_id
,
date_planned
,
order_lines
):
order_data
=
{
"partner_id"
:
int
(
supplier_id
),
"partner_ref"
:
False
,
"currency_id"
:
1
,
"date_order"
:
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
),
"origin"
:
"Aide à la commande"
,
"company_id"
:
1
,
"order_line"
:
[],
"notes"
:
False
,
"date_planned"
:
date_planned
,
"picking_type_id"
:
1
,
"dest_address_id"
:
False
,
"incoterm_id"
:
False
,
"payment_term_id"
:
False
,
"fiscal_position_id"
:
False
,
"message_follower_ids"
:
False
,
"message_ids"
:
False
}
for
line
in
order_lines
:
order_data
[
"order_line"
]
.
append
(
[
0
,
False
,
{
"package_qty"
:
line
[
"package_qty"
],
"price_policy"
:
"uom"
,
"indicative_package"
:
True
,
"product_id"
:
line
[
"product_variant_ids"
][
0
],
"name"
:
line
[
"name"
],
"date_planned"
:
date_planned
,
"account_analytic_id"
:
False
,
"product_qty_package"
:
line
[
"product_qty_package"
],
"product_qty"
:
line
[
"product_qty"
],
"product_uom"
:
line
[
"product_uom"
],
"price_unit"
:
line
[
"price_unit"
],
"discount"
:
0
,
"taxes_id"
:
[
[
6
,
False
,
line
[
"supplier_taxes_id"
]
]
]
}
]
)
api
=
OdooAPI
()
id_po
=
api
.
create
(
'purchase.order'
,
order_data
)
res_confirm
=
api
.
execute
(
'purchase.order'
,
'button_confirm'
,
[
id_po
])
res
=
{
'id_po'
:
id_po
,
'confirm_po'
:
True
}
return
res
class
Orders
(
models
.
Model
):
@staticmethod
...
...
orders/static/css/oders_helper_style.css
View file @
a15908ef
...
...
@@ -72,14 +72,20 @@
right
:
0
;
}
/* --
Supplier form
*/
#
supplier_form
_container
{
/* --
Order data
*/
#
order_data
_container
{
margin-top
:
30px
;
display
:
flex
;
justify-content
:
space-evenly
;
}
#supplier_input
{
width
:
500px
;
margin-right
:
10px
;
width
:
350px
;
border-radius
:
5px
;
}
#date_planned_input
{
margin-left
:
40px
;
border-radius
:
5px
;
}
...
...
@@ -89,7 +95,9 @@
}
#products_table_filter
input
{
height
:
40px
;
height
:
35px
;
width
:
300px
;
border-radius
:
10px
;
}
#table_header_select_all
{
...
...
@@ -125,6 +133,14 @@
cursor
:
pointer
;
}
/* -- Bottom action button */
#orders_creation_area
{
display
:
flex
;
justify-content
:
space-between
;
margin
:
15px
0
35px
0
;
}
/* -- Suppliers list */
#suppliers_container
{
display
:
flex
;
...
...
@@ -143,3 +159,54 @@
margin-left
:
5px
;
cursor
:
pointer
;
}
/* - Orders created screen */
.order_created_header
{
margin-top
:
15px
;
margin-bottom
:
40px
;
}
#created_orders_area
{
display
:
flex
;
flex-wrap
:
wrap
;
justify-content
:
space-evenly
;
}
.new_order_item
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
margin-top
:
20px
;
}
.download_order_file
{
margin-top
:
10px
;
}
.download_order_file_button
:hover
{
text-decoration
:
none
;
color
:
white
;
}
#recap_delivery_date
{
font-weight
:
bold
;
}
.mail_example_container
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
width
:
30%
;
margin
:
0
auto
;
}
.mail_type_text
{
width
:
100%
;
}
.mail_example
{
background-color
:
#e7e9ed
;
width
:
100%
;
padding
:
15px
;
}
\ No newline at end of file
orders/static/js/orders_helper.js
View file @
a15908ef
This diff is collapsed.
Click to expand it.
orders/urls.py
View file @
a15908ef
...
...
@@ -13,4 +13,6 @@ urlpatterns = [
url
(
r'^get_suppliers$'
,
views
.
get_suppliers
),
url
(
r'^get_supplier_products$'
,
views
.
get_supplier_products
),
url
(
r'^associate_supplier_to_product$'
,
views
.
associate_supplier_to_product
),
url
(
r'^create_orders$'
,
views
.
create_orders
),
url
(
r'^get_orders_attachment$'
,
views
.
get_orders_attachment
),
]
orders/views.py
View file @
a15908ef
...
...
@@ -7,6 +7,7 @@ from products.models import CagetteProduct, CagetteProducts
from
openpyxl
import
Workbook
from
openpyxl.writer.excel
import
save_virtual_workbook
import
datetime
def
as_text
(
value
):
return
str
(
value
)
if
value
is
not
None
else
""
...
...
@@ -17,7 +18,8 @@ def helper(request):
context
=
{
'title'
:
'Aide à la commande'
,
'couchdb_server'
:
settings
.
COUCHDB
[
'url'
],
'db'
:
settings
.
COUCHDB
[
'dbs'
][
'orders'
]
'db'
:
settings
.
COUCHDB
[
'dbs'
][
'orders'
],
'odoo_server'
:
settings
.
ODOO
[
'url'
]
}
template
=
loader
.
get_template
(
'orders/helper.html'
)
...
...
@@ -59,6 +61,48 @@ def associate_supplier_to_product(request):
return
JsonResponse
({
'res'
:
res
})
def
create_orders
(
request
):
""" Create products orders """
res
=
{
"created"
:
[]
}
try
:
data
=
json
.
loads
(
request
.
body
.
decode
())
# suppliers id are keys in request data
for
supplier_id
in
data
[
"suppliers_data"
]
.
keys
():
res_created
=
Order
.
create
(
supplier_id
,
data
[
"date_planned"
],
data
[
"suppliers_data"
][
supplier_id
])
res_created
[
"supplier_id"
]
=
supplier_id
res
[
"created"
]
.
append
(
res_created
)
except
Exception
as
e
:
res
[
"error"
]
=
str
(
e
)
return
JsonResponse
(
res
,
status
=
500
)
return
JsonResponse
({
'res'
:
res
})
def
get_orders_attachment
(
request
):
""" Get order attachment: order file created after PO is finalized """
res
=
[]
po_ids
=
request
.
GET
.
getlist
(
'po_ids'
)
for
id_po
in
po_ids
:
m
=
Order
(
int
(
id_po
))
attachment
=
m
.
get_order_attachment_id
()
if
'error'
in
attachment
:
res
.
append
(
attachment
)
else
:
res
.
append
({
'id_po'
:
id_po
,
'id_attachment'
:
attachment
[
"id"
]
})
for
item
in
res
:
if
'error'
in
item
:
return
JsonResponse
(
res
,
status
=
500
)
return
JsonResponse
({
'res'
:
res
})
def
export_one
(
request
,
oid
):
msg
=
''
try
:
...
...
@@ -66,7 +110,6 @@ def export_one(request, oid):
order
=
Order
(
oid
)
order_data
=
order
.
export
()
if
(
'success'
in
order_data
)
and
(
order_data
[
'success'
]
is
True
):
import
datetime
now
=
datetime
.
datetime
.
now
()
taxes
=
0
company_name
=
''
...
...
products/models.py
View file @
a15908ef
...
...
@@ -436,7 +436,7 @@ class CagetteProducts(models.Model):
today
=
datetime
.
date
.
today
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)
# Get products/supplier relation
f
=
[
"product_tmpl_id"
,
'date_start'
,
'date_end'
,
'package_qty'
]
f
=
[
"product_tmpl_id"
,
'date_start'
,
'date_end'
,
'package_qty'
,
'price'
]
c
=
[[
'name'
,
'='
,
int
(
supplier_id
)]]
psi
=
api
.
search_read
(
'product.supplierinfo'
,
c
,
f
)
...
...
@@ -449,21 +449,30 @@ class CagetteProducts(models.Model):
ptids
.
append
(
p
[
"product_tmpl_id"
][
0
])
# Get products templates
f
=
[
"id"
,
"state"
,
"name"
,
"default_code"
,
"qty_available"
,
"incoming_qty"
,
"uom_id"
,
"purchase_ok"
]
# TODO fetch only 'purchase_ok' products ?
f
=
[
"id"
,
"state"
,
"name"
,
"default_code"
,
"qty_available"
,
"incoming_qty"
,
"uom_id"
,
"purchase_ok"
,
"supplier_taxes_id"
,
"product_variant_ids"
]
c
=
[[
'id'
,
'in'
,
ptids
],
[
'purchase_ok'
,
'='
,
True
]]
products_t
=
api
.
search_read
(
'product.template'
,
c
,
f
)
filtered_products_t
=
[
p
for
p
in
products_t
if
p
[
"state"
]
!=
"end"
and
p
[
"state"
]
!=
"obsolete"
]
# Add
package qty
to product data
# Add
supplier data
to product data
for
i
,
fp
in
enumerate
(
filtered_products_t
):
psi_item
=
next
(
item
for
item
in
psi
if
item
[
"product_tmpl_id"
]
is
not
False
and
item
[
"product_tmpl_id"
][
0
]
==
fp
[
"id"
])
filtered_products_t
[
i
][
'supplierinfo'
]
=
{
'supplier_id'
:
supplier_id
,
'package_qty'
:
psi_item
[
"package_qty"
]
}
# Note: if product.product is needed, get "product_variant_ids" from product template
filtered_products_t
[
i
][
'suppliersinfo'
]
=
[{
'supplier_id'
:
int
(
supplier_id
),
'package_qty'
:
psi_item
[
"package_qty"
],
'price'
:
psi_item
[
"price"
]
}]
res
[
"products"
]
=
filtered_products_t
except
Exception
as
e
:
...
...
templates/orders/helper.html
View file @
a15908ef
...
...
@@ -24,17 +24,19 @@
</form>
</div>
<div
id=
"existing_orders_area"
>
<h2>
Ou, continuer une commande e
xistante
</h2>
<h2>
Ou, continuer une commande e
n cours de création
</h2>
<div
id=
"existing_orders"
></div>
</div>
</div>
<div
id=
"main_content"
class=
"page_content"
style=
"display:none;"
>
<div
id=
"back_to_order_selection"
>
<div
id=
"back_to_order_selection
_from_main
"
>
<button
type=
"button"
class=
"btn--danger"
><i
class=
"fas fa-arrow-left"
></i>
Retour
</button>
</div>
<div
id=
"actions_buttons_area"
>
<button
type=
"button"
class=
'btn--primary'
id=
"do_inventory"
>
Faire un inventaire
</button>
<button
type=
"button"
class=
'btn--primary'
id=
"do_inventory"
style=
"display:none;"
>
Faire un inventaire
</button>
</div>
<div
class=
"header txtcenter"
>
...
...
@@ -42,11 +44,12 @@
<i>
Commande :
<span
class=
"order_name_container"
></span></i>
</div>
<div
class=
"txtcenter"
id=
"
supplier_form
_container"
>
<div
class=
"txtcenter"
id=
"
order_data
_container"
>
<form
action=
"javascript:;"
id=
"supplier_form"
>
<input
type=
"text"
name=
"supplier"
id=
"supplier_input"
placeholder=
"Rechercher un fournisseur par son nom"
>
<button
type=
"submit"
class=
'btn--primary'
>
Ajouter le fournisseur
</button>
</form>
<input
type=
"text"
name=
"date_planned"
id=
"date_planned_input"
placeholder=
"Date de livraison souhaitée"
>
</div>
<div
class=
"txtcenter"
id=
"suppliers_container"
></div>
...
...
@@ -56,6 +59,40 @@
<table
id=
"products_table"
class=
"display"
cellspacing=
"0"
width=
"100%"
></table>
</div>
</div>
<div
id=
"orders_creation_area"
>
<div
class=
"add_product_container"
></div>
<button
type=
"button"
class=
'btn--primary'
id=
"create_orders"
style=
"display:none;"
>
Générer les commandes
</button>
</div>
</div>
<div
id=
"orders_created"
class=
"page_content"
style=
"display:none;"
>
<div
id=
"back_to_order_selection_from_orders_created"
>
<button
type=
"button"
class=
"btn--danger"
><i
class=
"fas fa-arrow-left"
></i>
Retour
</button>
</div>
<div
class=
"order_created_header txtcenter"
>
<h2>
Commandes créées !
</h2>
</div>
<div
class=
"txtcenter"
>
Livraison prévue le :
<span
id=
"recap_delivery_date"
>
XX/XX/XX
</span>
</div>
<div
id=
"created_orders_area"
></div>
<br/><br/><hr/><br/>
<div
class=
"mail_example_container"
>
<p
class=
"mail_type_text"
>
Mail type :
</p>
<div
class=
"mail_example"
>
Objet : Cde Cagette JJ/MM
<br/>
<br/>
Bonjour XXXXXXX,
<br/>
<br/>
Voici la commande de La Cagette pour le XX/XX/XX.
<br/>
<br/>
Merci d'avance,
<br/>
Bonne journée
</div>
</div>
</div>
<div
id=
"templates"
style=
"display:none;"
>
...
...
@@ -74,6 +111,19 @@
</div>
</div>
<div
id=
"new_order_item_template"
>
<div
class=
"new_order_item"
>
<h3
class=
"new_order_supplier_name"
></h3>
<h3
class=
"new_order_po"
></h3>
<div
class=
'download_order_file'
>
<i
class=
"fas fa-spinner fa-spin download_order_file_loading"
></i>
<a
class=
'btn--success download_order_file_button'
style=
"display:none;"
href=
"#"
>
Télécharger le fichier de commande
</a>
</div>
</div>
</div>
<div
id=
"modal_order_access"
>
<h3>
Attention !
</h3>
<br/>
...
...
@@ -126,6 +176,15 @@
<p>
Êtez-vous sûr ?
</p>
<hr/>
</div>
<div
id=
"modal_create_order"
>
<h3>
Attention !
</h3>
<p>
Vous vous apprêtez à générer les commandes à partir des données rentrées dans le tableau.
</p>
<p>
Êtez-vous sûr ?
</p>
<hr/>
</div>
</div>
</div>
...
...
@@ -134,6 +193,7 @@
<script
type=
"text/javascript"
>
var
couchdb_dbname
=
'{{db}}'
;
var
couchdb_server
=
'{{couchdb_server}}'
+
couchdb_dbname
;
var
odoo_server
=
'{{odoo_server}}'
;
</script>
<script
src=
"{% static "
js
/
all_common
.
js
"
%}?
v=
"></script>
<script type="
text
/
javascript
"
src=
"{% static 'js/orders_helper.js' %}?v="
></script>
...
...
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