Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Sebastian
erp5
Commits
d87b9db8
Commit
d87b9db8
authored
Feb 05, 2013
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reimplement fast=True for getTotalPrice/Quantity using inventory API
parent
5764dcc8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
121 additions
and
239 deletions
+121
-239
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/DeliveryLine_zGetTotal.xml
...teItem/portal_skins/erp5_trade/DeliveryLine_zGetTotal.xml
+0
-77
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/Delivery_zGetTotal.xml
...mplateItem/portal_skins/erp5_trade/Delivery_zGetTotal.xml
+0
-90
product/ERP5/Document/Delivery.py
product/ERP5/Document/Delivery.py
+51
-50
product/ERP5/Document/DeliveryLine.py
product/ERP5/Document/DeliveryLine.py
+24
-10
product/ERP5/Document/Order.py
product/ERP5/Document/Order.py
+4
-0
product/ERP5/tests/testOrder.py
product/ERP5/tests/testOrder.py
+42
-12
No files found.
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/DeliveryLine_zGetTotal.xml
deleted
100644 → 0
View file @
5764dcc8
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SQL"
module=
"Products.ZSQLMethods.SQL"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string>
uid
</string>
</value>
</item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
class_file_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
class_name_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_hook
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
<value>
<string>
erp5_sql_connection
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
DeliveryLine_zGetTotal
</string>
</value>
</item>
<item>
<key>
<string>
max_cache_
</string>
</key>
<value>
<int>
100
</int>
</value>
</item>
<item>
<key>
<string>
max_rows_
</string>
</key>
<value>
<int>
1000
</int>
</value>
</item>
<item>
<key>
<string>
src
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
SELECT \n
\tSUM(quantity) AS total_quantity, \n
\tSUM(quantity * price) AS total_price, \n
\tAVG(price) AS average_price\n
FROM catalog, movement\n
WHERE \n
\tcatalog.parent_uid = <dtml-sqlvar uid type="int">
\n
AND\t\n
\tcatalog.uid = movement.uid\n
]]>
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/Delivery_zGetTotal.xml
deleted
100644 → 0
View file @
5764dcc8
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"SQL"
module=
"Products.ZSQLMethods.SQL"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
allow_simple_one_argument_traversal
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
arguments_src
</string>
</key>
<value>
<string>
from_table_list:list\r\n
where_expression\r\n
order_by_expression
</string>
</value>
</item>
<item>
<key>
<string>
cache_time_
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
class_file_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
class_name_
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
connection_hook
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
connection_id
</string>
</key>
<value>
<string>
erp5_sql_connection
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Delivery_zGetTotal
</string>
</value>
</item>
<item>
<key>
<string>
max_cache_
</string>
</key>
<value>
<int>
100
</int>
</value>
</item>
<item>
<key>
<string>
max_rows_
</string>
</key>
<value>
<int>
1000
</int>
</value>
</item>
<item>
<key>
<string>
src
</string>
</key>
<value>
<string
encoding=
"cdata"
>
<![CDATA[
SELECT\n
SUM(movement.quantity) AS inventory,\n
SUM(movement.quantity) AS total_quantity,\n
SUM(movement.price * movement.quantity) AS total_price,\n
AVG(movement.price) AS average_price\n
\n
FROM\n
<dtml-in from_table_list>
<dtml-var
sequence-item
>
AS
<dtml-var
sequence-key
><dtml-if
sequence-end
><dtml-else>
,
</dtml-if></dtml-in>
\n
\n
WHERE\n
1=1\n
<dtml-if
where_expression
>
\n
AND
<dtml-var
where_expression
>
\n
</dtml-if>
\n
AND catalog.has_cell_content = 0\n
AND catalog.portal_type NOT IN ("Container", "Container Line", "Container Cell", "Simulation Movement")\n
\n
<dtml-if
order_by_expression
>
\n
ORDER BY
<dtml-var
order_by_expression
>
\n
</dtml-if>
\n
]]>
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/Document/Delivery.py
View file @
d87b9db8
...
...
@@ -91,6 +91,7 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
'getTotalPrice'
)
def
getTotalPrice
(
self
,
fast
=
0
,
src__
=
0
,
base_contribution
=
None
,
rounding
=
False
,
**
kw
):
""" Returns the total price for this order
if the `fast` argument is set to a true value, then it use
SQLCatalog to compute the price, otherwise it sums the total
price of objects one by one.
...
...
@@ -98,49 +99,51 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
So if the order is not in the catalog, getTotalPrice(fast=1)
will return 0, this is not a bug.
base_contribution must be a relative url of a category.
base_contribution must be a relative url of a category. If passed, then
fast parameter is ignored.
"""
result
=
None
if
not
fast
:
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalDeliveryMovementTypeList
())
if
base_contribution
is
None
:
result
=
sum
([
line
.
getTotalPrice
(
fast
=
0
)
for
line
in
self
.
objectValues
(
**
kw
)
])
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalDeliveryMovementTypeList
())
if
base_contribution
is
None
:
if
fast
:
# XXX fast ignores base_contribution for now, but it should be possible
# to use a related key
kw
[
'section_uid'
]
=
self
.
getDestinationSectionUid
()
kw
[
'stock.explanation_uid'
]
=
self
.
getUid
()
return
self
.
getPortalObject
()
\
.
portal_simulation
.
getInventoryAssetPrice
(
**
kw
)
result
=
sum
([
line
.
getTotalPrice
(
fast
=
0
)
for
line
in
self
.
objectValues
(
**
kw
)
])
else
:
# Find amounts from movements in the delivery.
if
isinstance
(
base_contribution
,
(
tuple
,
list
)):
base_contribution_list
=
base_contribution
else
:
# Find amounts from movements in the delivery.
if
isinstance
(
base_contribution
,
(
tuple
,
list
)):
base_contribution_list
=
base_contribution
else
:
base_contribution_list
=
(
base_contribution
,)
base_contribution_value_list
=
[]
portal_categories
=
self
.
portal_categories
for
relative_url
in
base_contribution_list
:
base_contribution_value
=
portal_categories
.
getCategoryValue
(
relative_url
)
if
base_contribution_value
is
not
None
:
base_contribution_value_list
.
append
(
base_contribution_value
)
if
not
base_contribution_value_list
:
# We cannot find any amount so that the result is 0.
result
=
0
else
:
base_contribution_list
=
(
base_contribution
,)
base_contribution_value_list
=
[]
portal_categories
=
self
.
portal_categories
for
relative_url
in
base_contribution_list
:
base_contribution_value
=
portal_categories
.
getCategoryValue
(
relative_url
)
if
base_contribution_value
is
not
None
:
base_contribution_value_list
.
append
(
base_contribution_value
)
if
not
base_contribution_value_list
:
# We cannot find any amount so that the result is 0.
result
=
0
else
:
matched_movement_list
=
[
movement
for
movement
in
self
.
getMovementList
()
if
set
(
movement
.
getBaseContributionValueList
()).
intersection
(
base_contribution_value_list
)]
if
rounding
:
portal_roundings
=
self
.
portal_roundings
matched_movement_list
=
[
movement
for
movement
in
self
.
getMovementList
()
if
set
(
movement
.
getBaseContributionValueList
()).
intersection
(
base_contribution_value_list
)]
if
rounding
:
portal_roundings
=
self
.
portal_roundings
matched_movement_list
=
[
portal_roundings
.
getRoundingProxy
(
movement
)
for
movement
in
matched_movement_list
]
result
=
sum
([
movement
.
getTotalPrice
()
for
movement
in
matched_movement_list
])
else
:
kw
[
'explanation_uid'
]
=
self
.
getUid
()
kw
.
update
(
self
.
portal_catalog
.
buildSQLQuery
(
**
kw
))
if
src__
:
return
self
.
Delivery_zGetTotal
(
src__
=
1
,
**
kw
)
aggregate
=
self
.
Delivery_zGetTotal
(
**
kw
)[
0
]
result
=
aggregate
.
total_price
or
0
portal_roundings
.
getRoundingProxy
(
movement
)
for
movement
in
matched_movement_list
]
result
=
sum
([
movement
.
getTotalPrice
()
for
movement
in
matched_movement_list
])
method
=
self
.
_getTypeBasedMethod
(
'convertTotalPrice'
)
if
method
is
not
None
:
return
method
(
result
)
...
...
@@ -164,6 +167,7 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
'getTotalQuantity'
)
def
getTotalQuantity
(
self
,
fast
=
0
,
src__
=
0
,
**
kw
):
""" Returns the total quantity of this order.
if the `fast` argument is set to a true value, then it use
SQLCatalog to compute the quantity, otherwise it sums the total
quantity of objects one by one.
...
...
@@ -171,17 +175,14 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
So if the order is not in the catalog, getTotalQuantity(fast=1)
will return 0, this is not a bug.
"""
if
not
fast
:
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalDeliveryMovementTypeList
())
return
sum
([
line
.
getTotalQuantity
(
fast
=
0
)
for
line
in
self
.
objectValues
(
**
kw
)
])
kw
[
'explanation_uid'
]
=
self
.
getUid
()
kw
.
update
(
self
.
portal_catalog
.
buildSQLQuery
(
**
kw
))
if
src__
:
return
self
.
Delivery_zGetTotal
(
src__
=
1
,
**
kw
)
aggregate
=
self
.
Delivery_zGetTotal
(
**
kw
)[
0
]
return
aggregate
.
total_quantity
or
0
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalDeliveryMovementTypeList
())
if
fast
:
kw
[
'section_uid'
]
=
self
.
getDestinationSectionUid
()
kw
[
'stock.explanation_uid'
]
=
self
.
getUid
()
return
self
.
getPortalObject
().
portal_simulation
.
getInventory
(
**
kw
)
return
sum
([
line
.
getTotalQuantity
(
fast
=
0
)
for
line
in
self
.
objectValues
(
**
kw
)
])
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getDeliveryUid'
)
...
...
product/ERP5/Document/DeliveryLine.py
View file @
d87b9db8
...
...
@@ -116,16 +116,23 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, ImmobilisationMovement):
if hasLineContent: return sum of lines total price
if hasCellContent: return sum of cells total price
else: return quantity * price
if fast is argument true, then a SQL method will be used.
"""
if fast argument is true, inventory API will be used.
"""
if
fast
:
kw
=
{}
kw
[
'section_uid'
]
=
self
.
getDestinationSectionUid
()
kw
[
'stock.explanation_uid'
]
=
self
.
getExplanationUid
()
kw
[
'relative_url'
]
=
(
'%s/%%'
%
(
self
.
getRelativeUrl
().
replace
(
'_'
,
'
\
\
_'
)),
self
.
getRelativeUrl
()
)
kw
[
'only_accountable'
]
=
False
return
self
.
getPortalObject
().
portal_simulation
.
getInventoryAssetPrice
(
**
kw
)
if
self
.
hasLineContent
():
meta_type
=
self
.
meta_type
return
sum
(
l
.
getTotalPrice
(
context
=
context
)
for
l
in
self
.
objectValues
()
if
l
.
meta_type
==
meta_type
)
elif
not
self
.
hasCellContent
(
base_id
=
'movement'
):
return
Movement
.
_getTotalPrice
(
self
,
default
=
default
,
context
=
context
)
elif
fast
:
# Use MySQL
return
self
.
DeliveryLine_zGetTotal
()[
0
].
total_price
or
0.0
return
sum
(
cell
.
getTotalPrice
(
default
=
0.0
,
context
=
context
)
for
cell
in
self
.
getCellValueList
())
...
...
@@ -138,20 +145,27 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, ImmobilisationMovement):
if hasLineContent: return sum of lines total quantity
if hasCellContent: return sum of cells total quantity
else: return quantity
if fast argument is true,
then a SQL method
will be used.
if fast argument is true,
inventory API
will be used.
"""
if
fast
:
kw
=
{}
kw
[
'section_uid'
]
=
self
.
getDestinationSectionUid
()
kw
[
'stock.explanation_uid'
]
=
self
.
getExplanationUid
()
kw
[
'relative_url'
]
=
(
'%s/%%'
%
(
self
.
getRelativeUrl
().
replace
(
'_'
,
'
\
\
_'
)),
self
.
getRelativeUrl
()
)
kw
[
'only_accountable'
]
=
False
return
self
.
getPortalObject
().
portal_simulation
.
getInventory
(
**
kw
)
base_id
=
'movement'
if
self
.
hasLineContent
():
meta_type
=
self
.
meta_type
return
sum
(
l
.
getTotalQuantity
()
for
l
in
self
.
objectValues
()
if
l
.
meta_type
==
meta_type
)
elif
self
.
hasCellContent
(
base_id
=
base_id
):
if
fast
:
# Use MySQL
aggregate
=
self
.
DeliveryLine_zGetTotal
()[
0
]
return
aggregate
.
total_quantity
or
0.0
return
sum
([
cell
.
getQuantity
()
for
cell
in
self
.
getCellValueList
()])
else
:
return
self
.
getQuantity
()
return
self
.
getQuantity
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'hasLineContent'
)
...
...
product/ERP5/Document/Order.py
View file @
d87b9db8
...
...
@@ -72,6 +72,8 @@ class Order(Delivery):
If base_contribution is passed, the trade model lines will be used to
include movements that will be generated.
"""
if
kw
.
get
(
'fast'
):
kw
[
'only_accountable'
]
=
False
rounding
=
kw
.
get
(
'rounding'
)
if
kw
.
get
(
'base_contribution'
)
is
None
:
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalOrderMovementTypeList
())
...
...
@@ -118,6 +120,8 @@ class Order(Delivery):
def
getTotalQuantity
(
self
,
**
kw
)
:
"""Returns the total quantity for this Order. """
kw
.
setdefault
(
'portal_type'
,
self
.
getPortalOrderMovementTypeList
())
if
kw
.
get
(
'fast'
):
kw
[
'only_accountable'
]
=
False
return
Delivery
.
getTotalQuantity
(
self
,
**
kw
)
@
deprecated
...
...
product/ERP5/tests/testOrder.py
View file @
d87b9db8
...
...
@@ -353,19 +353,30 @@ class TestOrderMixin(SubcontentReindexingWrapper):
def
stepCheckOrder
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
"""
Check if order was well created
"""
organisation
=
sequence
.
get
(
'organisation'
)
project
=
sequence
.
get
(
'project'
)
Check if order was well created, either by stepCreateOrder of
stepSetOrderProfile
"""
source_organisation
=
sequence
.
get
(
'organisation1'
)
if
source_organisation
is
None
:
source_organisation
=
sequence
.
get
(
'organisation'
)
destination_organisation
=
sequence
.
get
(
'organisation2'
)
if
destination_organisation
is
None
:
destination_organisation
=
sequence
.
get
(
'organisation'
)
source_project
=
sequence
.
get
(
'project1'
)
if
source_project
is
None
:
source_project
=
sequence
.
get
(
'project'
)
destination_project
=
sequence
.
get
(
'project2'
)
if
destination_project
is
None
:
destination_project
=
sequence
.
get
(
'project'
)
order
=
sequence
.
get
(
'order'
)
self
.
assertEquals
(
self
.
datetime
+
10
,
order
.
getStartDate
())
self
.
assertEquals
(
self
.
datetime
+
20
,
order
.
getStopDate
())
self
.
assertEquals
(
organisation
,
order
.
getSourceValue
())
self
.
assertEquals
(
organisation
,
order
.
getDestinationValue
())
self
.
assertEquals
(
organisation
,
order
.
getSourceSectionValue
())
self
.
assertEquals
(
organisation
,
order
.
getDestinationSectionValue
())
self
.
assertEquals
(
project
,
order
.
getSourceProjectValue
())
self
.
assertEquals
(
project
,
order
.
getDestinationProjectValue
())
self
.
assertEquals
(
source_
organisation
,
order
.
getSourceValue
())
self
.
assertEquals
(
destination_
organisation
,
order
.
getDestinationValue
())
self
.
assertEquals
(
source_
organisation
,
order
.
getSourceSectionValue
())
self
.
assertEquals
(
destination_
organisation
,
order
.
getDestinationSectionValue
())
self
.
assertEquals
(
source_
project
,
order
.
getSourceProjectValue
())
self
.
assertEquals
(
destination_
project
,
order
.
getDestinationProjectValue
())
def
stepCreateOrderLine
(
self
,
sequence
=
None
,
sequence_list
=
None
,
**
kw
):
...
...
@@ -736,7 +747,7 @@ class TestOrderMixin(SubcontentReindexingWrapper):
order_line_list
=
map
(
lambda
x
:
x
.
getObject
(),
order_line_list
)
total_price
=
0
for
order_line
in
order_line_list
:
total_price
+=
order_line
.
getTotalPrice
(
fast
=
0
)
total_price
+=
order_line
.
getTotalPrice
()
self
.
assertEquals
(
0
,
len
(
portal_catalog
(
relative_url
=
order
.
getRelativeUrl
())))
self
.
assertEquals
(
total_price
,
order
.
getTotalPrice
(
fast
=
0
))
self
.
assertNotEquals
(
total_price
,
0
)
...
...
@@ -1148,7 +1159,12 @@ class TestOrderMixin(SubcontentReindexingWrapper):
'adopt_prevision_action'
)
non_variated_order_creation
=
'
\
stepCreateOrganisation1
\
stepCreateOrganisation2
\
stepCreateProject1
\
stepCreateProject2
\
stepCreateOrder
\
stepSetOrderProfile
\
stepCreateNotVariatedResource
\
stepCreateOrderLine
\
stepCheckOrderLineEmptyMatrix
\
...
...
@@ -1158,7 +1174,12 @@ class TestOrderMixin(SubcontentReindexingWrapper):
'
variated_order_line_creation
=
'
\
stepCreateOrganisation1
\
stepCreateOrganisation2
\
stepCreateProject1
\
stepCreateProject2
\
stepCreateOrder
\
stepSetOrderProfile
\
stepCreateVariatedResource
\
stepCreateOrderLine
\
'
...
...
@@ -1590,7 +1611,12 @@ class TestOrder(TestOrderMixin, ERP5TypeTestCase):
sequence_list
=
SequenceList
()
# Test with positive price order line and negative price order line.
sequence_string
=
'
\
stepCreateOrganisation1
\
stepCreateOrganisation2
\
stepCreateProject1
\
stepCreateProject2
\
stepCreateOrder
\
stepSetOrderProfile
\
stepCheckOrderTotalQuantity
\
stepCreateNotVariatedResource
\
stepCreateOrderLine
\
...
...
@@ -2250,11 +2276,15 @@ class TestOrder(TestOrderMixin, ERP5TypeTestCase):
"""
if
not
run
:
return
portal
=
self
.
getPortal
()
portal
=
self
.
portal
base_id
=
'movement'
order_line_vcl
=
[
'size/Baby'
]
section
=
portal
.
organisation_module
.
newContent
(
portal_type
=
'Organisation'
)
order_module
=
portal
.
getDefaultModule
(
portal_type
=
self
.
order_portal_type
)
order
=
order_module
.
newContent
(
portal_type
=
self
.
order_portal_type
,
destination_section_value
=
section
,
destination_value
=
section
,
specialise
=
self
.
business_process
)
# No line, no movement
self
.
assertEquals
(
order
.
getTotalQuantity
(
fast
=
0
),
0
)
...
...
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