Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
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
1
Merge Requests
1
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
Romain Courteaud
slapos.core
Commits
a472982c
Commit
a472982c
authored
Oct 19, 2021
by
Romain Courteaud
🐸
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos_accounting: generate one open order per instance tree
parent
3b9c5ef9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
245 additions
and
390 deletions
+245
-390
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/InstanceTree_requestUpdateOpenSaleOrder.py
...pos_accounting/InstanceTree_requestUpdateOpenSaleOrder.py
+125
-4
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/OpenSaleOrder_updatePeriod.py
...tal_skins/slapos_accounting/OpenSaleOrder_updatePeriod.py
+82
-3
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/Person_storeOpenSaleOrderJournal.py
...ins/slapos_accounting/Person_storeOpenSaleOrderJournal.py
+0
-242
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/Person_storeOpenSaleOrderJournal.xml
...ns/slapos_accounting/Person_storeOpenSaleOrderJournal.xml
+0
-62
master/bt5/slapos_accounting/TestTemplateItem/portal_components/test.erp5.testSlapOSAccountingAlarm.py
.../portal_components/test.erp5.testSlapOSAccountingAlarm.py
+25
-65
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseDefaultScenarioMixin.py
...omponents/test.erp5.SlapOSTestCaseDefaultScenarioMixin.py
+8
-13
master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py
...al_components/test.erp5.testSlapOSSubscriptionScenario.py
+5
-1
No files found.
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/InstanceTree_requestUpdateOpenSaleOrder.py
View file @
a472982c
...
@@ -2,11 +2,132 @@ from zExceptions import Unauthorized
...
@@ -2,11 +2,132 @@ from zExceptions import Unauthorized
if
REQUEST
is
not
None
:
if
REQUEST
is
not
None
:
raise
Unauthorized
raise
Unauthorized
if
context
.
getCausalityState
()
==
'diverged'
:
from
DateTime
import
DateTime
person
=
context
.
getDestinationSectionValue
(
portal_type
=
"Person"
)
portal
=
context
.
getPortalObject
()
instance_tree
=
context
now
=
DateTime
()
tag
=
'%s_%s'
%
(
instance_tree
.
getUid
(),
script
.
id
)
activate_kw
=
{
'tag'
:
tag
}
if
portal
.
portal_activities
.
countMessageWithTag
(
tag
)
>
0
:
# nothing to do
return
def
storeWorkflowComment
(
document
,
comment
):
portal
.
portal_workflow
.
doActionFor
(
document
,
'edit_action'
,
comment
=
comment
)
def
newOpenOrder
(
open_sale_order
):
open_sale_order_template
=
portal
.
restrictedTraverse
(
portal
.
portal_preferences
.
getPreferredOpenSaleOrderTemplate
())
open_order_edit_kw
=
{
'effective_date'
:
DateTime
(),
'activate_kw'
:
activate_kw
,
'source'
:
open_sale_order_template
.
getSource
(),
'source_section'
:
open_sale_order_template
.
getSourceSection
()
}
if
open_sale_order
is
None
:
new_open_sale_order
=
open_sale_order_template
.
Base_createCloneDocument
(
batch_mode
=
1
)
open_order_edit_kw
.
update
({
'destination'
:
person
.
getRelativeUrl
(),
'destination_decision'
:
person
.
getRelativeUrl
(),
'title'
:
"%s SlapOS Subscription"
%
person
.
getTitle
(),
})
else
:
new_open_sale_order
=
open_sale_order
.
Base_createCloneDocument
(
batch_mode
=
1
)
open_sale_order
.
setExpirationDate
(
now
,
activate_kw
=
activate_kw
)
new_open_sale_order
.
edit
(
**
open_order_edit_kw
)
new_open_sale_order
.
order
(
activate_kw
=
activate_kw
)
new_open_sale_order
.
validate
(
activate_kw
=
activate_kw
)
return
new_open_sale_order
if
instance_tree
.
getCausalityState
()
==
'diverged'
:
person
=
instance_tree
.
getDestinationSectionValue
(
portal_type
=
"Person"
)
# Template document does not have person relation
# Template document does not have person relation
if
person
is
not
None
:
if
person
is
not
None
:
person
.
Person_storeOpenSaleOrderJournal
()
# Search an existing related open order
open_order_line
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Open Sale Order Line'
,
default_aggregate_uid
=
instance_tree
.
getUid
())
is_open_order_creation_needed
=
False
# Simply check that it has never been simulated
if
instance_tree
.
getSlapState
()
==
'destroy_requested'
:
# Line should be deleted
if
(
open_order_line
is
not
None
)
and
(
open_order_line
.
getValidationState
()
==
"invalidated"
):
instance_tree
.
converge
(
comment
=
"Last open order: %s"
%
open_order_line
.
getRelativeUrl
())
elif
open_order_line
is
None
:
# User has no Open Sale Order (likely), so we add the line to remove later. This allow us to charge
# eventual usage between the runs of the alarm.
is_open_order_creation_needed
=
True
elif
open_order_line
is
None
:
# Let's add
is_open_order_creation_needed
=
True
# Let's create the open order
if
is_open_order_creation_needed
:
open_sale_order
=
newOpenOrder
(
None
)
open_order_explanation
=
""
# Add lines
open_sale_order_line_template
=
portal
.
restrictedTraverse
(
portal
.
portal_preferences
.
getPreferredOpenSaleOrderLineTemplate
())
open_sale_order_line
=
open_sale_order_line_template
.
Base_createCloneDocument
(
batch_mode
=
1
,
destination
=
open_sale_order
)
start_date
=
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
edit_kw
=
{}
subscription_request
=
instance_tree
.
getAggregateRelatedValue
(
portal_type
=
"Subscription Request"
)
# Define the start date of the period, this can variates with the time.
# start_date_delta = 0
if
subscription_request
is
not
None
:
# Copy from Subscription Condition the source and Source Section into the line
# RAFAEL: As the model is use single Open Order, it isn't possible to use multiple
# companies per region, so we rely on Subscription Conditions to Describe the
# providers.
edit_kw
[
"source"
]
=
subscription_request
.
getSource
()
edit_kw
[
"source_section"
]
=
subscription_request
.
getSourceSection
()
# Quantity is double because the first invoice has to
# charge for 2 months
edit_kw
[
'quantity'
]
=
subscription_request
.
getQuantity
()
edit_kw
[
'price'
]
=
subscription_request
.
getPrice
()
edit_kw
[
'price_currency'
]
=
subscription_request
.
getPriceCurrency
()
# While create move the start date to be at least 1 months
# So we can charge 3 months at once
# You can increase 65 days to generate 3 months
# You can increase 32 days to generate 2 months
# You can increase 0 days to keep generating one month only
# start_date_delta = 0
open_sale_order_line
.
edit
(
activate_kw
=
activate_kw
,
title
=
instance_tree
.
getTitle
(),
start_date
=
start_date
,
# Ensure stop date value is higher than start date
# it will be updated by OpenSaleOrder_updatePeriod
stop_date
=
start_date
+
1
,
# stop_date=calculateOpenOrderLineStopDate(open_sale_order_line,
# instance_tree, start_date_delta=start_date_delta),
aggregate_value
=
instance_tree
,
**
edit_kw
)
storeWorkflowComment
(
open_sale_order_line
,
"Created for %s"
%
instance_tree
.
getRelativeUrl
())
# instance_tree.converge(comment="Last open order: %s" % open_sale_order_line.getRelativeUrl())
open_order_explanation
=
"Added %s."
%
str
(
open_sale_order_line
.
getId
())
storeWorkflowComment
(
open_sale_order
,
open_order_explanation
)
else
:
open_sale_order
=
open_order_line
.
getParentValue
()
open_sale_order
.
OpenSaleOrder_updatePeriod
()
# Person_storeOpenSaleOrderJournal should fix all divergent Instance Tree in one run
# Person_storeOpenSaleOrderJournal should fix all divergent Instance Tree in one run
assert
context
.
getCausalityState
()
==
'solved'
assert
instance_tree
.
getCausalityState
()
==
'solved'
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/OpenSaleOrder_updatePeriod.py
View file @
a472982c
...
@@ -2,7 +2,86 @@ from zExceptions import Unauthorized
...
@@ -2,7 +2,86 @@ from zExceptions import Unauthorized
if
REQUEST
is
not
None
:
if
REQUEST
is
not
None
:
raise
Unauthorized
raise
Unauthorized
if
context
.
getValidationState
()
==
'validated'
:
from
erp5.component.module.DateUtils
import
addToDate
person
=
context
.
getDestinationDecisionValue
(
portal_type
=
"Person"
)
from
DateTime
import
DateTime
portal
=
context
.
getPortalObject
()
open_sale_order
=
context
now
=
DateTime
()
tag
=
'%s_%s'
%
(
open_sale_order
.
getUid
(),
script
.
id
)
activate_kw
=
{
'tag'
:
tag
}
if
portal
.
portal_activities
.
countMessageWithTag
(
tag
)
>
0
:
# nothing to do
return
def
storeWorkflowComment
(
document
,
comment
):
portal
.
portal_workflow
.
doActionFor
(
document
,
'edit_action'
,
comment
=
comment
)
def
calculateOpenOrderLineStopDate
(
open_order_line
,
instance_tree
,
start_date_delta
,
next_stop_date_delta
=
0
):
end_date
=
instance_tree
.
InstanceTree_calculateSubscriptionStopDate
()
if
end_date
is
None
:
# Be sure that start date is different from stop date
# Consider the first period longer (delta), this allow us to change X days/months
# On a first invoice.
next_stop_date
=
instance_tree
.
getNextPeriodicalDate
(
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
+
start_date_delta
)
current_stop_date
=
next_stop_date
# Ensure the invoice is generated 15 days in advance of the next period.
while
next_stop_date
<
now
+
next_stop_date_delta
:
# Return result should be < now, it order to provide stability in simulation (destruction if it happen should be >= now)
current_stop_date
=
next_stop_date
next_stop_date
=
\
instance_tree
.
getNextPeriodicalDate
(
current_stop_date
)
return
addToDate
(
current_stop_date
,
to_add
=
{
'second'
:
-
1
})
else
:
stop_date
=
end_date
return
stop_date
if
open_sale_order
.
getValidationState
()
==
'validated'
:
person
=
open_sale_order
.
getDestinationDecisionValue
(
portal_type
=
"Person"
)
if
person
is
not
None
:
if
person
is
not
None
:
person
.
Person_storeOpenSaleOrderJournal
()
for
open_order_line
in
open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
):
current_start_date
=
open_order_line
.
getStartDate
()
current_stop_date
=
open_order_line
.
getStopDate
()
# Prevent mistakes
assert
current_start_date
is
not
None
assert
current_stop_date
is
not
None
assert
current_start_date
<
current_stop_date
instance_tree
=
open_order_line
.
getAggregateValue
(
portal_type
=
'Instance Tree'
)
assert
current_start_date
==
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
subscription_request
=
instance_tree
.
getAggregateRelatedValue
(
portal_type
=
"Subscription Request"
)
# Define the start date of the period, this can variates with the time.
next_stop_date_delta
=
0
if
subscription_request
is
not
None
:
next_stop_date_delta
=
46
# First check if the instance tree has been correctly simulated (this script may run only once per year...)
stop_date
=
calculateOpenOrderLineStopDate
(
open_order_line
,
instance_tree
,
start_date_delta
=
0
,
next_stop_date_delta
=
next_stop_date_delta
)
if
current_stop_date
<
stop_date
:
# Bingo, new subscription to generate
open_order_line
.
edit
(
stop_date
=
stop_date
,
activate_kw
=
activate_kw
)
storeWorkflowComment
(
open_order_line
,
'Stop date updated to %s'
%
stop_date
)
if
instance_tree
.
getSlapState
()
==
'destroy_requested'
:
# Line should be deleted
assert
instance_tree
.
getCausalityState
()
==
'diverged'
instance_tree
.
converge
(
comment
=
"Last open order: %s"
%
open_order_line
.
getRelativeUrl
())
open_sale_order
.
archive
()
storeWorkflowComment
(
open_sale_order
,
"Instance Tree destroyed: %s"
%
instance_tree
.
getRelativeUrl
())
elif
(
instance_tree
.
getCausalityState
()
==
'diverged'
):
instance_tree
.
converge
(
comment
=
"Nothing to do on open order."
)
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/Person_storeOpenSaleOrderJournal.py
deleted
100644 → 0
View file @
3b9c5ef9
from
erp5.component.module.DateUtils
import
addToDate
from
DateTime
import
DateTime
portal
=
context
.
getPortalObject
()
now
=
DateTime
()
person
=
context
tag
=
'%s_%s'
%
(
person
.
getUid
(),
script
.
id
)
activate_kw
=
{
'tag'
:
tag
}
if
portal
.
portal_activities
.
countMessageWithTag
(
tag
)
>
0
:
# nothing to do
return
def
newOpenOrder
(
open_sale_order
):
open_sale_order_template
=
portal
.
restrictedTraverse
(
portal
.
portal_preferences
.
getPreferredOpenSaleOrderTemplate
())
open_order_edit_kw
=
{
'effective_date'
:
DateTime
(),
'activate_kw'
:
activate_kw
,
'source'
:
open_sale_order_template
.
getSource
(),
'source_section'
:
open_sale_order_template
.
getSourceSection
()
}
if
open_sale_order
is
None
:
new_open_sale_order
=
open_sale_order_template
.
Base_createCloneDocument
(
batch_mode
=
1
)
open_order_edit_kw
.
update
({
'destination'
:
person
.
getRelativeUrl
(),
'destination_decision'
:
person
.
getRelativeUrl
(),
'title'
:
"%s SlapOS Subscription"
%
person
.
getTitle
(),
})
else
:
new_open_sale_order
=
open_sale_order
.
Base_createCloneDocument
(
batch_mode
=
1
)
open_sale_order
.
setExpirationDate
(
now
,
activate_kw
=
activate_kw
)
new_open_sale_order
.
edit
(
**
open_order_edit_kw
)
new_open_sale_order
.
order
(
activate_kw
=
activate_kw
)
new_open_sale_order
.
validate
(
activate_kw
=
activate_kw
)
return
new_open_sale_order
def
storeWorkflowComment
(
document
,
comment
):
portal
.
portal_workflow
.
doActionFor
(
document
,
'edit_action'
,
comment
=
comment
)
def
calculateOpenOrderLineStopDate
(
open_order_line
,
instance_tree
,
start_date_delta
,
next_stop_date_delta
=
0
):
end_date
=
instance_tree
.
InstanceTree_calculateSubscriptionStopDate
()
if
end_date
is
None
:
# Be sure that start date is different from stop date
# Consider the first period longer (delta), this allow us to change X days/months
# On a first invoice.
next_stop_date
=
instance_tree
.
getNextPeriodicalDate
(
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
+
start_date_delta
)
current_stop_date
=
next_stop_date
# Ensure the invoice is generated 15 days in advance of the next period.
while
next_stop_date
<
now
+
next_stop_date_delta
:
# Return result should be < now, it order to provide stability in simulation (destruction if it happen should be >= now)
current_stop_date
=
next_stop_date
next_stop_date
=
\
instance_tree
.
getNextPeriodicalDate
(
current_stop_date
)
return
addToDate
(
current_stop_date
,
to_add
=
{
'second'
:
-
1
})
else
:
stop_date
=
end_date
return
stop_date
# Prevent concurrent transaction to update the open order
context
.
serialize
()
# First, check the existing open order. Does some lines need to be removed, updated?
open_sale_order_list
=
portal
.
portal_catalog
(
default_destination_uid
=
person
.
getUid
(),
portal_type
=
"Open Sale Order"
,
validation_state
=
"validated"
,
limit
=
2
,
)
open_sale_order_count
=
len
(
open_sale_order_list
)
if
open_sale_order_count
==
0
:
open_sale_order
=
None
elif
open_sale_order_count
==
1
:
open_sale_order
=
open_sale_order_list
[
0
].
getObject
()
else
:
raise
ValueError
,
"Too many open order '%s' found: %s"
%
(
person
.
getRelativeUrl
(),
[
x
.
path
for
x
in
open_sale_order_list
])
delete_line_list
=
[]
add_line_list
=
[]
updated_instance_tree_dict
=
{}
deleted_instance_tree_dict
=
{}
if
open_sale_order
is
not
None
:
for
open_order_line
in
open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
):
current_start_date
=
open_order_line
.
getStartDate
()
current_stop_date
=
open_order_line
.
getStopDate
()
# Prevent mistakes
assert
current_start_date
is
not
None
assert
current_stop_date
is
not
None
assert
current_start_date
<
current_stop_date
instance_tree
=
open_order_line
.
getAggregateValue
(
portal_type
=
'Instance Tree'
)
assert
current_start_date
==
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
subscription_request
=
instance_tree
.
getAggregateRelatedValue
(
portal_type
=
"Subscription Request"
)
# Define the start date of the period, this can variates with the time.
next_stop_date_delta
=
0
if
subscription_request
is
not
None
:
next_stop_date_delta
=
46
# First check if the instance tree has been correctly simulated (this script may run only once per year...)
stop_date
=
calculateOpenOrderLineStopDate
(
open_order_line
,
instance_tree
,
start_date_delta
=
0
,
next_stop_date_delta
=
next_stop_date_delta
)
if
current_stop_date
<
stop_date
:
# Bingo, new subscription to generate
open_order_line
.
edit
(
stop_date
=
stop_date
,
activate_kw
=
activate_kw
)
storeWorkflowComment
(
open_order_line
,
'Stop date updated to %s'
%
stop_date
)
if
instance_tree
.
getSlapState
()
==
'destroy_requested'
:
# Line should be deleted
assert
instance_tree
.
getCausalityState
()
==
'diverged'
delete_line_list
.
append
(
open_order_line
.
getId
())
instance_tree
.
converge
(
comment
=
"Last open order: %s"
%
open_order_line
.
getRelativeUrl
())
deleted_instance_tree_dict
[
instance_tree
.
getRelativeUrl
()]
=
None
updated_instance_tree_dict
[
instance_tree
.
getRelativeUrl
()]
=
None
elif
(
instance_tree
.
getCausalityState
()
==
'diverged'
):
instance_tree
.
converge
(
comment
=
"Nothing to do on open order."
)
updated_instance_tree_dict
[
instance_tree
.
getRelativeUrl
()]
=
None
# Time to check the open order line to add (remaining diverged Hosting
# Subscription normally)
for
instance_tree
in
portal
.
portal_catalog
(
portal_type
=
'Instance Tree'
,
default_destination_section_uid
=
context
.
getUid
(),
causality_state
=
"diverged"
):
instance_tree
=
instance_tree
.
getObject
()
if
instance_tree
.
getCausalityState
()
==
'diverged'
:
# Simply check that it has never been simulated
if
instance_tree
.
getSlapState
()
==
'destroy_requested'
:
# Line should be deleted
open_order_line
=
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Open Sale Order Line'
,
default_aggregate_uid
=
instance_tree
.
getUid
())
if
open_order_line
is
not
None
and
open_order_line
.
getValidationState
()
==
"invalidated"
:
instance_tree
.
converge
(
comment
=
"Last open order: %s"
%
open_order_line
.
getRelativeUrl
())
elif
open_order_line
is
None
:
# User has no Open Sale Order (likely), so we add the line to remove later. This allow us to charge
# eventual usage between the runs of the alarm.
add_line_list
.
append
(
instance_tree
)
else
:
assert
len
(
portal
.
portal_catalog
(
portal_type
=
'Open Sale Order Line'
,
default_aggregate_uid
=
instance_tree
.
getUid
(),
limit
=
1
))
==
0
# Let's add
add_line_list
.
append
(
instance_tree
)
else
:
# Should be in the list of lines to remove
assert
(
instance_tree
.
getRelativeUrl
()
in
deleted_instance_tree_dict
)
or
\
(
instance_tree
.
getRelativeUrl
()
in
updated_instance_tree_dict
)
manual_archive
=
False
if
(
add_line_list
):
# No need to create a new open order to add lines
if
open_sale_order
is
None
:
open_sale_order
=
newOpenOrder
(
None
)
manual_archive
=
True
open_order_explanation
=
""
# Add lines
added_line_list
=
[]
open_sale_order_line_template
=
portal
.
restrictedTraverse
(
portal
.
portal_preferences
.
getPreferredOpenSaleOrderLineTemplate
())
for
instance_tree
in
add_line_list
:
open_sale_order_line
=
open_sale_order_line_template
.
Base_createCloneDocument
(
batch_mode
=
1
,
destination
=
open_sale_order
)
start_date
=
instance_tree
.
InstanceTree_calculateSubscriptionStartDate
()
edit_kw
=
{}
subscription_request
=
instance_tree
.
getAggregateRelatedValue
(
portal_type
=
"Subscription Request"
)
# Define the start date of the period, this can variates with the time.
start_date_delta
=
0
if
subscription_request
is
not
None
:
# Copy from Subscription Condition the source and Source Section into the line
# RAFAEL: As the model is use single Open Order, it isn't possible to use multiple
# companies per region, so we rely on Subscription Conditions to Describe the
# providers.
edit_kw
[
"source"
]
=
subscription_request
.
getSource
()
edit_kw
[
"source_section"
]
=
subscription_request
.
getSourceSection
()
# Quantity is double because the first invoice has to
# charge for 2 months
edit_kw
[
'quantity'
]
=
subscription_request
.
getQuantity
()
edit_kw
[
'price'
]
=
subscription_request
.
getPrice
()
edit_kw
[
'price_currency'
]
=
subscription_request
.
getPriceCurrency
()
# While create move the start date to be at least 1 months
# So we can charge 3 months at once
# You can increase 65 days to generate 3 months
# You can increase 32 days to generate 2 months
# You can increase 0 days to keep generating one month only
start_date_delta
=
0
open_sale_order_line
.
edit
(
activate_kw
=
activate_kw
,
title
=
instance_tree
.
getTitle
(),
start_date
=
start_date
,
stop_date
=
calculateOpenOrderLineStopDate
(
open_sale_order_line
,
instance_tree
,
start_date_delta
=
start_date_delta
),
aggregate_value
=
instance_tree
,
**
edit_kw
)
storeWorkflowComment
(
open_sale_order_line
,
"Created for %s"
%
instance_tree
.
getRelativeUrl
())
if
(
instance_tree
.
getSlapState
()
==
'destroy_requested'
):
# Added line to delete immediately
delete_line_list
.
append
(
open_sale_order_line
.
getId
())
instance_tree
.
converge
(
comment
=
"Last open order: %s"
%
open_sale_order_line
.
getRelativeUrl
())
else
:
instance_tree
.
converge
(
comment
=
"First open order: %s"
%
open_sale_order_line
.
getRelativeUrl
())
added_line_list
.
append
(
open_sale_order_line
.
getId
())
open_order_explanation
+=
"Added %s."
%
str
(
added_line_list
)
new_open_sale_order
=
None
if
(
delete_line_list
):
# All Verifications done. Time to clone/create open order
new_open_sale_order
=
newOpenOrder
(
open_sale_order
)
if
manual_archive
==
True
:
open_sale_order
.
archive
()
open_order_explanation
=
""
# Remove lines
new_open_sale_order
.
deleteContent
(
delete_line_list
)
open_order_explanation
+=
"Removed %s."
%
str
(
delete_line_list
)
storeWorkflowComment
(
new_open_sale_order
,
open_order_explanation
)
open_sale_order
=
new_open_sale_order
if
open_sale_order
is
not
None
:
if
not
len
(
open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)):
open_sale_order
.
archive
()
master/bt5/slapos_accounting/SkinTemplateItem/portal_skins/slapos_accounting/Person_storeOpenSaleOrderJournal.xml
deleted
100644 → 0
View file @
3b9c5ef9
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
Script_magic
</string>
</key>
<value>
<int>
3
</int>
</value>
</item>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Person_storeOpenSaleOrderJournal
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_accounting/TestTemplateItem/portal_components/test.erp5.testSlapOSAccountingAlarm.py
View file @
a472982c
...
@@ -107,22 +107,6 @@ class TestOpenSaleOrderAlarm(SlapOSTestCaseMixin):
...
@@ -107,22 +107,6 @@ class TestOpenSaleOrderAlarm(SlapOSTestCaseMixin):
default_destination_uid
=
person
.
getUid
()
default_destination_uid
=
person
.
getUid
()
))
))
def
test_OSO_after_Person_updateOpenSaleOrder
(
self
):
person
=
self
.
portal
.
person_module
.
template_member
\
.
Base_createCloneDocument
(
batch_mode
=
1
)
self
.
tic
()
person
.
Person_storeOpenSaleOrderJournal
()
self
.
tic
()
open_sale_order_list
=
self
.
portal
.
portal_catalog
(
validation_state
=
'validated'
,
portal_type
=
'Open Sale Order'
,
default_destination_uid
=
person
.
getUid
()
)
# No need to create any open order without instance tree
self
.
assertEqual
(
0
,
len
(
open_sale_order_list
))
@
simulateByEditWorkflowMark
(
'InstanceTree_requestUpdateOpenSaleOrder'
)
@
simulateByEditWorkflowMark
(
'InstanceTree_requestUpdateOpenSaleOrder'
)
def
test_alarm_HS_diverged
(
self
):
def
test_alarm_HS_diverged
(
self
):
subscription
=
self
.
portal
.
instance_tree_module
\
subscription
=
self
.
portal
.
instance_tree_module
\
...
@@ -291,28 +275,22 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -291,28 +275,22 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
default_destination_uid
=
person
.
getUid
()
default_destination_uid
=
person
.
getUid
()
)
)
self
.
assertEqual
(
2
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
1
,
len
(
open_sale_order_list
))
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'validated'
]
if
q
.
getValidationState
()
==
'validated'
]
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'archived'
]
if
q
.
getValidationState
()
==
'archived'
]
self
.
assertEqual
(
0
,
len
(
validated_open_sale_order_list
))
self
.
assertEqual
(
0
,
len
(
validated_open_sale_order_list
))
self
.
assertEqual
(
2
,
len
(
archived_open_sale_order_list
))
self
.
assertEqual
(
1
,
len
(
archived_open_sale_order_list
))
archived_open_sale_order_list
.
sort
(
key
=
lambda
x
:
x
.
getCreationDate
())
last_open_sale_order
=
archived_open_sale_order_list
[
-
1
].
getObject
()
archived_open_sale_order
=
archived_open_sale_order_list
[
0
]
\
archived_open_sale_order
=
archived_open_sale_order_list
[
0
]
\
.
getObject
()
.
getObject
()
self
.
assertEqual
(
open_sale_order
.
getRelativeUrl
(),
self
.
assertEqual
(
open_sale_order
.
getRelativeUrl
(),
archived_open_sale_order
.
getRelativeUrl
())
archived_open_sale_order
.
getRelativeUrl
())
last_line_list
=
last_open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
archived_line_list
=
archived_open_sale_order
.
contentValues
(
archived_line_list
=
archived_open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
0
,
len
(
last_line_list
))
self
.
assertEqual
(
1
,
len
(
archived_line_list
))
self
.
assertEqual
(
1
,
len
(
archived_line_list
))
archived_line
=
archived_line_list
[
0
].
getObject
()
archived_line
=
archived_line_list
[
0
].
getObject
()
...
@@ -376,7 +354,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -376,7 +354,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
default_destination_uid
=
person
.
getUid
()
default_destination_uid
=
person
.
getUid
()
)
)
self
.
assertEqual
(
2
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
1
,
len
(
open_sale_order_list
))
archived_open_sale_order_list
=
[
x
for
x
in
open_sale_order_list
\
archived_open_sale_order_list
=
[
x
for
x
in
open_sale_order_list
\
if
x
.
getValidationState
()
!=
'validated'
and
\
if
x
.
getValidationState
()
!=
'validated'
and
\
len
(
x
.
objectValues
())
>
0
]
len
(
x
.
objectValues
())
>
0
]
...
@@ -421,7 +399,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -421,7 +399,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
self
.
assertEqual
(
'archived'
,
new_open_sale_order
.
getValidationState
())
self
.
assertEqual
(
'archived'
,
new_open_sale_order
.
getValidationState
())
open_sale_order_line_list
=
new_open_sale_order
.
contentValues
(
open_sale_order_line_list
=
new_open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
0
,
len
(
open_sale_order_line_list
))
self
.
assertEqual
(
1
,
len
(
open_sale_order_line_list
))
def
test_two_InstanceTree
(
self
):
def
test_two_InstanceTree
(
self
):
person
=
self
.
portal
.
person_module
.
template_member
\
person
=
self
.
portal
.
person_module
.
template_member
\
...
@@ -517,18 +495,23 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -517,18 +495,23 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
default_destination_uid
=
person
.
getUid
()
default_destination_uid
=
person
.
getUid
()
)
)
self
.
assertEqual
(
1
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
2
,
len
(
open_sale_order_list
))
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'validated'
]
if
q
.
getValidationState
()
==
'validated'
]
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'archived'
]
if
q
.
getValidationState
()
==
'archived'
]
self
.
assertEqual
(
1
,
len
(
validated_open_sale_order_list
))
self
.
assertEqual
(
2
,
len
(
validated_open_sale_order_list
))
self
.
assertEqual
(
0
,
len
(
archived_open_sale_order_list
))
self
.
assertEqual
(
0
,
len
(
archived_open_sale_order_list
))
validated_open_sale_order
=
validated_open_sale_order_list
[
0
].
getObject
()
validated_line_list
=
validated_open_sale_order
.
contentValues
(
open_sale_order_2
=
[
x
for
x
in
validated_open_sale_order_list
if
x
.
getRelativeUrl
()
!=
open_sale_order
.
getRelativeUrl
()][
0
]
self
.
assertEqual
(
open_sale_order
.
getRelativeUrl
(),
[
x
for
x
in
validated_open_sale_order_list
if
x
.
getRelativeUrl
()
==
open_sale_order
.
getRelativeUrl
()][
0
].
getRelativeUrl
())
validated_line_list
=
open_sale_order_2
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
2
,
len
(
validated_line_list
))
self
.
assertEqual
(
1
,
len
(
validated_line_list
))
validated_line_2
=
validated_line_list
[
0
]
validated_line_1
=
line
self
.
assertEqual
(
open_sale_order_line_template
.
getQuantity
(),
self
.
assertEqual
(
open_sale_order_line_template
.
getQuantity
(),
line
.
getQuantity
())
line
.
getQuantity
())
...
@@ -543,10 +526,8 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -543,10 +526,8 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
next_stop_date_2
=
addToDate
(
stop_date_2
,
to_add
=
{
'month'
:
1
})
next_stop_date_2
=
addToDate
(
stop_date_2
,
to_add
=
{
'month'
:
1
})
stop_date_2
=
addToDate
(
stop_date_2
,
to_add
=
{
'second'
:
-
1
})
stop_date_2
=
addToDate
(
stop_date_2
,
to_add
=
{
'second'
:
-
1
})
validated_line_1
=
[
q
for
q
in
validated_line_list
if
q
.
getAggregate
()
==
\
self
.
assertEqual
(
validated_line_1
.
getAggregate
(),
subscription
.
getRelativeUrl
())
subscription
.
getRelativeUrl
()][
0
]
self
.
assertEqual
(
validated_line_2
.
getAggregate
(),
subscription2
.
getRelativeUrl
())
validated_line_2
=
[
q
for
q
in
validated_line_list
if
q
.
getAggregate
()
==
\
subscription2
.
getRelativeUrl
()][
0
]
self
.
assertTrue
(
all
([
q
in
validated_line_1
.
getCategoryList
()
\
self
.
assertTrue
(
all
([
q
in
validated_line_1
.
getCategoryList
()
\
for
q
in
open_sale_order_line_template
.
getCategoryList
()]))
for
q
in
open_sale_order_line_template
.
getCategoryList
()]))
...
@@ -667,7 +648,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -667,7 +648,7 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
default_destination_uid
=
person
.
getUid
()
default_destination_uid
=
person
.
getUid
()
)
)
self
.
assertEqual
(
2
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
1
,
len
(
open_sale_order_list
))
archived_open_sale_order_list
=
[
x
for
x
in
open_sale_order_list
\
archived_open_sale_order_list
=
[
x
for
x
in
open_sale_order_list
\
if
x
.
getValidationState
()
!=
'validated'
]
if
x
.
getValidationState
()
!=
'validated'
]
...
@@ -680,7 +661,6 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -680,7 +661,6 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
portal_type
=
'Open Sale Order Line'
)
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
1
,
len
(
open_sale_order_line_list
))
self
.
assertEqual
(
1
,
len
(
open_sale_order_line_list
))
effective_date
=
open_sale_order
.
getEffectiveDate
()
line
=
open_sale_order_line_list
[
0
].
getObject
()
line
=
open_sale_order_line_list
[
0
].
getObject
()
self
.
assertEqual
(
subscription
.
getRelativeUrl
(),
line
.
getAggregate
())
self
.
assertEqual
(
subscription
.
getRelativeUrl
(),
line
.
getAggregate
())
...
@@ -698,19 +678,6 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
...
@@ -698,19 +678,6 @@ class TestInstanceTree_requestUpdateOpenSaleOrder(SlapOSTestCaseMixin):
self
.
assertEqual
(
addToDate
(
line
.
getStartDate
(),
to_add
=
{
'day'
:
1
}),
self
.
assertEqual
(
addToDate
(
line
.
getStartDate
(),
to_add
=
{
'day'
:
1
}),
line
.
getStopDate
())
line
.
getStopDate
())
archived_open_sale_order_list
=
[
x
for
x
in
open_sale_order_list
\
if
x
.
getValidationState
()
!=
'validated'
]
archived_open_sale_order_list
.
sort
(
key
=
lambda
x
:
x
.
getCreationDate
())
new_open_sale_order
=
archived_open_sale_order_list
[
-
1
].
getObject
()
self
.
assertEqual
(
'archived'
,
new_open_sale_order
.
getValidationState
())
new_effective_date
=
new_open_sale_order
.
getEffectiveDate
()
open_sale_order_line_list
=
new_open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
0
,
len
(
open_sale_order_line_list
))
self
.
assertTrue
(
new_effective_date
>
effective_date
,
"%s <= %s"
%
(
new_effective_date
,
effective_date
))
class
TestSlapOSTriggerBuildAlarm
(
SlapOSTestCaseMixin
):
class
TestSlapOSTriggerBuildAlarm
(
SlapOSTestCaseMixin
):
@
simulateByTitlewMark
(
'SimulationMovement_buildSlapOS'
)
@
simulateByTitlewMark
(
'SimulationMovement_buildSlapOS'
)
...
@@ -1262,14 +1229,11 @@ class TestSlapOSUpdateOpenSaleOrderPeriod(SlapOSTestCaseMixin):
...
@@ -1262,14 +1229,11 @@ class TestSlapOSUpdateOpenSaleOrderPeriod(SlapOSTestCaseMixin):
open_order
.
edit
(
open_order
.
edit
(
destination_decision_value
=
person
,
destination_decision_value
=
person
,
)
)
open_order
.
newContent
(
portal_type
=
"Open Sale Order Line"
)
script_name
=
"Person_storeOpenSaleOrderJournal"
self
.
assertRaises
(
AssertionError
,
open_order
.
OpenSaleOrder_updatePeriod
)
self
.
_simulateScript
(
script_name
)
try
:
open_order
.
OpenSaleOrder_updatePeriod
()
finally
:
self
.
_dropScript
(
script_name
)
self
.
assertScriptVisited
(
person
,
script_name
)
def
test_updatePeriod_invalidated
(
self
):
def
test_updatePeriod_invalidated
(
self
):
open_order
=
self
.
createOpenOrder
()
open_order
=
self
.
createOpenOrder
()
...
@@ -1279,14 +1243,10 @@ class TestSlapOSUpdateOpenSaleOrderPeriod(SlapOSTestCaseMixin):
...
@@ -1279,14 +1243,10 @@ class TestSlapOSUpdateOpenSaleOrderPeriod(SlapOSTestCaseMixin):
destination_decision_value
=
person
,
destination_decision_value
=
person
,
)
)
open_order
.
invalidate
()
open_order
.
invalidate
()
open_order
.
newContent
(
script_name
=
"Person_storeOpenSaleOrderJournal"
portal_type
=
"Open Sale Order Line"
self
.
_simulateScript
(
script_name
)
)
try
:
open_order
.
OpenSaleOrder_updatePeriod
()
open_order
.
OpenSaleOrder_updatePeriod
()
finally
:
self
.
_dropScript
(
script_name
)
self
.
assertScriptNotVisited
(
person
,
script_name
)
def
test_alarm
(
self
):
def
test_alarm
(
self
):
open_order
=
self
.
createOpenOrder
()
open_order
=
self
.
createOpenOrder
()
...
...
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseDefaultScenarioMixin.py
View file @
a472982c
...
@@ -617,18 +617,19 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
...
@@ -617,18 +617,19 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
self
.
assertEqual
(
0
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
0
,
len
(
open_sale_order_list
))
return
return
self
.
assertEqual
(
2
,
len
(
open_sale_order_list
))
self
.
assertEqual
(
len
(
instance_tree_list
)
,
len
(
open_sale_order_list
))
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
archived_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'archived'
]
if
q
.
getValidationState
()
==
'archived'
]
self
.
assertEqual
(
len
(
instance_tree_list
),
len
(
archived_open_sale_order_list
))
archived_open_sale_order_list
.
sort
(
key
=
lambda
x
:
x
.
getCreationDate
())
line_list
=
[]
for
open_sale_order
in
archived_open_sale_order_list
:
# Select the first archived
archived_line_list
=
open_sale_order
.
contentValues
(
open_sale_order
=
archived_open_sale_order_list
[
0
]
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
1
,
len
(
archived_line_list
))
line_list
.
extend
(
archived_line_list
)
line_list
=
open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
len
(
instance_tree_list
),
len
(
line_list
))
self
.
assertEqual
(
len
(
instance_tree_list
),
len
(
line_list
))
self
.
assertSameSet
(
self
.
assertSameSet
(
[
q
.
getRelativeUrl
()
for
q
in
instance_tree_list
],
[
q
.
getRelativeUrl
()
for
q
in
instance_tree_list
],
...
@@ -637,15 +638,9 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
...
@@ -637,15 +638,9 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
validated_open_sale_order_list
=
[
q
for
q
in
open_sale_order_list
if
q
.
getValidationState
()
==
'validated'
]
if
q
.
getValidationState
()
==
'validated'
]
# if no line, all open orders are kept archived
# if no line, all open orders are kept archived
self
.
assertEqual
(
len
(
validated_open_sale_order_list
),
0
)
self
.
assertEqual
(
len
(
validated_open_sale_order_list
),
0
)
latest_open_sale_order
=
archived_open_sale_order_list
[
-
1
]
line_list
=
latest_open_sale_order
.
contentValues
(
portal_type
=
'Open Sale Order Line'
)
self
.
assertEqual
(
len
(
line_list
),
0
)
def
findMessage
(
self
,
email
,
body
):
def
findMessage
(
self
,
email
,
body
):
for
candidate
in
reversed
(
self
.
portal
.
MailHost
.
getMessageList
()):
for
candidate
in
reversed
(
self
.
portal
.
MailHost
.
getMessageList
()):
if
[
q
for
q
in
candidate
[
1
]
if
email
in
q
]
and
body
in
candidate
[
2
]:
if
[
q
for
q
in
candidate
[
1
]
if
email
in
q
]
and
body
in
candidate
[
2
]:
...
...
master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py
View file @
a472982c
...
@@ -1652,8 +1652,12 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
...
@@ -1652,8 +1652,12 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
software_type
=
"default"
,
software_type
=
"default"
,
partition_reference
=
"_test_subscription_scenario_with_existing_user_extra_instance"
,
partition_reference
=
"_test_subscription_scenario_with_existing_user_extra_instance"
,
)
)
self
.
non_subscription_related_instance_amount
=
1
self
.
non_subscription_related_instance_amount
=
1
# Trigger open order creation
self
.
portal
.
portal_alarms
.
slapos_request_update_instance_tree_open_sale_order
.
activeSense
()
self
.
tic
()
self
.
login
()
self
.
login
()
self
.
requestAndCheckInstanceTree
(
self
.
requestAndCheckInstanceTree
(
amount
,
name
,
default_email_text
)
amount
,
name
,
default_email_text
)
...
...
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