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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
alecs_myu
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