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
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
Titouan Soulard
slapos.core
Commits
edef233e
Commit
edef233e
authored
Oct 02, 2024
by
Romain Courteaud
🐸
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos_panel: action to change a Subscription price
parent
c1b7e30f
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1215 additions
and
0 deletions
+1215
-0
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
...Item/portal_components/test.erp5.testSlapOSCodingStyle.py
+1
-0
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SubscriptionScenario.py
...omponents/test.erp5.testSlapOSERP5SubscriptionScenario.py
+326
-0
master/bt5/slapos_panel/ActionTemplateItem/portal_types/Subscription%20Request/change_slapos_submitted_price.xml
.../Subscription%20Request/change_slapos_submitted_price.xml
+96
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.py
...apos_panel/SubscriptionRequest_changeFromPayableToFree.py
+116
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.xml
...pos_panel/SubscriptionRequest_changeFromPayableToFree.xml
+62
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
...s_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
+75
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
..._panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
+62
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
...scriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
+160
-0
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
...quest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
+316
-0
master/bt5/slapos_panel/bt/template_action_path_list
master/bt5/slapos_panel/bt/template_action_path_list
+1
-0
No files found.
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSCodingStyle.py
View file @
edef233e
...
@@ -272,6 +272,7 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
...
@@ -272,6 +272,7 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
'slapos_panel/SoftwareInstance_getNewsDict'
,
'slapos_panel/SoftwareInstance_getNewsDict'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareRelease'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareRelease'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareType'
,
'slapos_panel/SoftwareProduct_addSlapOSSoftwareType'
,
'slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice'
,
'slapos_panel/SubscriptionRequest_jumpToPaymentPage'
,
'slapos_panel/SubscriptionRequest_jumpToPaymentPage'
,
'slapos_panel/Ticket_addSlapOSEvent'
,
'slapos_panel/Ticket_addSlapOSEvent'
,
'slapos_panel/Ticket_closeSlapOS'
,
'slapos_panel/Ticket_closeSlapOS'
,
...
...
master/bt5/slapos_erp5/TestTemplateItem/portal_components/test.erp5.testSlapOSERP5SubscriptionScenario.py
View file @
edef233e
...
@@ -553,3 +553,329 @@ class TestSlapOSSubscriptionScenario(TestSlapOSSubscriptionScenarioMixin):
...
@@ -553,3 +553,329 @@ class TestSlapOSSubscriptionScenario(TestSlapOSSubscriptionScenarioMixin):
# 2 subscription requests
# 2 subscription requests
self
.
assertRelatedObjectCount
(
project
,
24
)
self
.
assertRelatedObjectCount
(
project
,
24
)
self
.
checkERP5StateBeforeExit
()
self
.
checkERP5StateBeforeExit
()
def
checkInstanceAllocationFromPayableToFree
(
self
,
person_user_id
,
person_reference
,
instance_title
,
software_release
,
software_type
,
server
,
project_reference
,
deposit_amount
,
currency
,
sale_person
):
self
.
login
(
person_user_id
)
self
.
personRequestInstanceNotReady
(
software_release
=
software_release
,
software_type
=
software_type
,
partition_reference
=
instance_title
,
project_reference
=
project_reference
)
self
.
tic
()
instance_tree
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"Instance Tree"
,
title
=
instance_title
,
follow_up__reference
=
project_reference
)
person
=
instance_tree
.
getDestinationSectionValue
()
self
.
assertEqual
(
person
.
getUserId
(),
person_user_id
)
subscription_request
=
self
.
checkServiceSubscriptionRequest
(
instance_tree
,
'submitted'
)
self
.
assertEqual
(
subscription_request
.
getTotalPrice
(),
deposit_amount
)
self
.
tic
()
outstanding_amount_list
=
person
.
Entity_getOutstandingDepositAmountList
(
currency
.
getUid
(),
ledger_uid
=
subscription_request
.
getLedgerUid
())
self
.
assertEqual
(
sum
([
i
.
total_price
for
i
in
outstanding_amount_list
]),
deposit_amount
)
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
self
.
logout
()
self
.
login
(
sale_person
.
getUserId
())
#previous_trade_condition = subscription_request.getSpecialiseValue()
subscription_request
.
SubscriptionRequest_changeFromPayableToFree
(
None
)
self
.
tic
()
self
.
logout
()
self
.
login
(
person
.
getUserId
())
# Ensure to pay from the website
#outstanding_amount = self.web_site.restrictedTraverse(outstanding_amount_list[0].getRelativeUrl())
#outstanding_amount.Base_createExternalPaymentTransactionFromOutstandingAmountAndRedirect()
self
.
tic
()
self
.
logout
()
self
.
login
()
payment_transaction
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"Payment Transaction"
,
destination_section_uid
=
person
.
getUid
(),
simulation_state
=
"started"
)
self
.
assertEqual
(
payment_transaction
,
None
)
self
.
login
(
person_user_id
)
self
.
checkServiceSubscriptionRequest
(
instance_tree
,
'cancelled'
)
amount
=
sum
([
i
.
total_price
for
i
in
person
.
Entity_getOutstandingDepositAmountList
(
currency
.
getUid
(),
ledger_uid
=
subscription_request
.
getLedgerUid
())])
self
.
assertEqual
(
0
,
amount
)
self
.
login
(
person_user_id
)
self
.
personRequestInstance
(
software_release
=
software_release
,
software_type
=
software_type
,
partition_reference
=
instance_title
,
project_reference
=
project_reference
)
# now instantiate it on compute_node and set some nice connection dict
self
.
simulateSlapgridCP
(
server
)
# let's find instances of user and check connection strings
instance_tree_list
=
[
q
.
getObject
()
for
q
in
self
.
_getCurrentInstanceTreeList
()
if
q
.
getTitle
()
==
instance_title
]
self
.
assertEqual
(
1
,
len
(
instance_tree_list
))
instance_tree
=
instance_tree_list
[
0
]
software_instance
=
instance_tree
.
getSuccessorValue
()
self
.
assertEqual
(
software_instance
.
getTitle
(),
instance_tree
.
getTitle
())
connection_dict
=
software_instance
.
getConnectionXmlAsDict
()
self
.
assertSameSet
((
'url_1'
,
'url_2'
),
connection_dict
.
keys
())
self
.
login
()
partition
=
software_instance
.
getAggregateValue
()
self
.
assertSameSet
(
[
'http://%s/'
%
q
.
getIpAddress
()
for
q
in
partition
.
contentValues
(
portal_type
=
'Internet Protocol Address'
)],
connection_dict
.
values
())
def
test_virtual_master_with_accounting_scenario_from_payable_to_free
(
self
):
with
PinnedDateTime
(
self
,
DateTime
(
'2024/02/17'
)):
currency
,
_
,
_
,
sale_person
,
_
=
self
.
bootstrapVirtualMasterTest
()
self
.
logout
()
# lets join as slapos administrator, which will manager the project
project_owner_reference
=
'project-%s'
%
self
.
generateNewId
()
self
.
joinSlapOS
(
self
.
web_site
,
project_owner_reference
)
self
.
login
()
project_owner_person
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"ERP5 Login"
,
reference
=
project_owner_reference
).
getParentValue
()
# owner_person.setCareerSubordinationValue(seller_organisation)
self
.
tic
()
self
.
logout
()
self
.
login
(
sale_person
.
getUserId
())
project_relative_url
=
self
.
addProject
(
is_accountable
=
True
,
person
=
project_owner_person
,
currency
=
currency
)
self
.
logout
()
self
.
login
()
project
=
self
.
portal
.
restrictedTraverse
(
project_relative_url
)
preference
=
self
.
portal
.
portal_preferences
.
slapos_default_system_preference
preference
.
edit
(
preferred_subscription_assignment_category_list
=
[
'function/customer'
,
'role/client'
,
'destination_project/%s'
%
project
.
getRelativeUrl
()
]
)
public_server_software
=
self
.
generateNewSoftwareReleaseUrl
()
public_instance_type
=
'public type'
software_product
,
release_variation
,
type_variation
=
self
.
addSoftwareProduct
(
"instance product"
,
project
,
public_server_software
,
public_instance_type
)
self
.
logout
()
self
.
login
(
sale_person
.
getUserId
())
sale_supply
=
self
.
portal
.
sale_supply_module
.
newContent
(
portal_type
=
"Sale Supply"
,
title
=
"price for %s"
%
project
.
getRelativeUrl
(),
source_project_value
=
project
,
price_currency_value
=
currency
)
sale_supply
.
newContent
(
portal_type
=
"Sale Supply Line"
,
base_price
=
9
,
resource_value
=
software_product
)
sale_supply
.
newContent
(
portal_type
=
"Sale Supply Line"
,
base_price
=
99
,
resource
=
"service_module/slapos_compute_node_subscription"
)
sale_supply
.
validate
()
self
.
tic
()
# some preparation
self
.
logout
()
# lets join as slapos administrator, which will own few compute_nodes
owner_reference
=
'owner-%s'
%
self
.
generateNewId
()
self
.
joinSlapOS
(
self
.
web_site
,
owner_reference
)
self
.
login
()
owner_person
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"ERP5 Login"
,
reference
=
owner_reference
).
getParentValue
()
# first slapos administrator assignment can only be created by
# the erp5 manager
self
.
addProjectProductionManagerAssignment
(
owner_person
,
project
)
self
.
tic
()
# hooray, now it is time to create compute_nodes
self
.
login
(
owner_person
.
getUserId
())
public_server_title
=
'Public Server for %s'
%
owner_reference
public_server_id
=
self
.
requestComputeNode
(
public_server_title
,
project
.
getReference
())
public_server
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'Compute Node'
,
reference
=
public_server_id
)
self
.
setAccessToMemcached
(
public_server
)
self
.
assertNotEqual
(
None
,
public_server
)
self
.
setServerOpenPublic
(
public_server
)
public_server
.
generateCertificate
()
self
.
addAllocationSupply
(
"for compute node"
,
public_server
,
software_product
,
release_variation
,
type_variation
)
# and install some software on them
self
.
supplySoftware
(
public_server
,
public_server_software
)
# format the compute_nodes
self
.
formatComputeNode
(
public_server
)
self
.
logout
()
self
.
login
(
project_owner_person
.
getUserId
())
# Pay deposit to validate virtual master + one computer
deposit_amount
=
42.0
+
99.0
ledger
=
self
.
portal
.
portal_categories
.
ledger
.
automated
outstanding_amount_list
=
project_owner_person
.
Entity_getOutstandingDepositAmountList
(
currency
.
getUid
(),
ledger_uid
=
ledger
.
getUid
())
amount
=
sum
([
i
.
total_price
for
i
in
outstanding_amount_list
])
self
.
assertEqual
(
amount
,
deposit_amount
)
# Ensure to pay from the website
outstanding_amount
=
self
.
web_site
.
restrictedTraverse
(
outstanding_amount_list
[
0
].
getRelativeUrl
())
outstanding_amount
.
Base_createExternalPaymentTransactionFromOutstandingAmountAndRedirect
()
self
.
tic
()
self
.
logout
()
self
.
login
()
payment_transaction
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"Payment Transaction"
,
destination_section_uid
=
project_owner_person
.
getUid
(),
simulation_state
=
"started"
)
self
.
assertEqual
(
payment_transaction
.
getSpecialiseValue
().
getTradeConditionType
(),
"deposit"
)
# payzen/wechat or accountant will only stop the payment
payment_transaction
.
stop
()
self
.
tic
()
assert
payment_transaction
.
receivable
.
getGroupingReference
(
None
)
is
not
None
self
.
login
(
project_owner_person
.
getUserId
())
amount
=
sum
([
i
.
total_price
for
i
in
project_owner_person
.
Entity_getOutstandingDepositAmountList
(
currency
.
getUid
(),
ledger_uid
=
ledger
.
getUid
())])
self
.
assertEqual
(
0
,
amount
)
self
.
logout
()
# join as the another visitor and request software instance on public
# compute_node
self
.
logout
()
public_reference
=
'public-%s'
%
self
.
generateNewId
()
self
.
joinSlapOS
(
self
.
web_site
,
public_reference
)
self
.
login
()
public_person
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
"ERP5 Login"
,
reference
=
public_reference
).
getParentValue
()
with
PinnedDateTime
(
self
,
DateTime
(
'2024/02/17 01:01'
)):
public_instance_title
=
'Public title %s'
%
self
.
generateNewId
()
# Request a payable instance without deposit
# Change the subscription from payable to free
self
.
checkInstanceAllocationFromPayableToFree
(
public_person
.
getUserId
(),
public_reference
,
public_instance_title
,
public_server_software
,
public_instance_type
,
public_server
,
project
.
getReference
(),
9.0
,
currency
,
sale_person
)
self
.
login
()
public_person
=
self
.
portal
.
portal_catalog
.
getResultValue
(
portal_type
=
'ERP5 Login'
,
reference
=
public_reference
).
getParentValue
()
self
.
login
(
owner_person
.
getUserId
())
# and the instances
self
.
checkInstanceUnallocation
(
public_person
.
getUserId
(),
public_reference
,
public_instance_title
,
public_server_software
,
public_instance_type
,
public_server
,
project
.
getReference
())
# and uninstall some software on them
self
.
logout
()
self
.
login
(
owner_person
.
getUserId
())
self
.
supplySoftware
(
public_server
,
public_server_software
,
state
=
'destroyed'
)
self
.
logout
()
# Uninstall from compute_node
self
.
login
()
self
.
simulateSlapgridSR
(
public_server
)
self
.
tic
()
# Check stock
inventory_list
=
self
.
portal
.
portal_simulation
.
getCurrentInventoryList
(
**
{
'group_by_section'
:
False
,
'group_by_node'
:
True
,
'group_by_variation'
:
True
,
'resource_uid'
:
software_product
.
getUid
(),
'node_uid'
:
public_person
.
getUid
(),
'project_uid'
:
None
,
'ledger_uid'
:
self
.
portal
.
portal_categories
.
ledger
.
automated
.
getUid
()
})
assert
len
(
inventory_list
)
==
1
,
len
(
inventory_list
)
assert
inventory_list
[
0
].
quantity
==
1
,
inventory_list
[
0
].
quantity
resource_vcl
=
[
# 'software_release/%s' % release_variation.getRelativeUrl(),
'software_type/%s'
%
type_variation
.
getRelativeUrl
()
]
resource_vcl
.
sort
()
assert
inventory_list
[
0
].
getVariationCategoryList
()
==
resource_vcl
,
"%s %s"
%
(
resource_vcl
,
inventory_list
[
0
].
getVariationCategoryList
())
# Check accounting
transaction_list
=
self
.
portal
.
account_module
.
receivable
.
Account_getAccountingTransactionList
(
mirror_section_uid
=
public_person
.
getUid
())
assert
len
(
transaction_list
)
==
0
,
len
(
transaction_list
)
self
.
login
()
# Ensure no unexpected object has been created
# 2 accounting transaction / line
# 3 allocation supply / line / cell
# 1 compute node
# 2 credential request
# 2 event
# 1 instance tree
# 6 open sale order / line
# 5 (can reduce to 2) assignment
# 10 simulation mvt
# 3 packing list / line
# 3 sale supply / line
# 3 sale trade condition
# 1 software installation
# 1 software instance
# 1 software product
# 1 subscription change request
# 4 subscription requests
self
.
assertRelatedObjectCount
(
project
,
49
)
self
.
checkERP5StateBeforeExit
()
master/bt5/slapos_panel/ActionTemplateItem/portal_types/Subscription%20Request/change_slapos_submitted_price.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_jio_action
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_jio_action
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
change_slapos_submitted_price
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
60.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Change Submitted Price
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
python: portal.Base_checkPermission(\'subscription_change_request_module\', \'Add portal content\') and (context.getSimulationState() == \'submitted\')
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.py
0 → 100644
View file @
edef233e
portal
=
context
.
getPortalObject
()
Base_translateString
=
portal
.
Base_translateString
subscription_request
=
context
from
zExceptions
import
Unauthorized
if
REQUEST
is
not
None
:
raise
Unauthorized
batch
=
(
dialog_id
is
None
)
trade_condition_type
=
'manual'
if
activate_kw
is
None
:
activate_kw
=
{}
if
not
'tag'
in
activate_kw
:
activate_kw
[
'tag'
]
=
script
.
id
if
not
(
subscription_request
.
hasSourceSection
()
and
(
0
<
subscription_request
.
getPrice
(
0
))):
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'The Subscription Request is not a payable one'
)
}
if
batch
:
return
subscription_request
return
context
.
Base_renderForm
(
dialog_id
,
keep_items
=
keep_items
)
# Create the Subscription Change Request
item
=
subscription_request
.
getAggregateValue
()
if
item
.
getPortalType
()
==
'Project'
:
project
=
item
else
:
project
=
subscription_request
.
getSourceProjectValue
()
customer
=
subscription_request
.
getDestinationValue
()
try
:
subscription_change_request
=
subscription_request
.
getResourceValue
().
Resource_createSubscriptionRequest
(
customer
,
# [software_type, software_release],
subscription_request
.
getVariationCategoryList
(),
project
,
currency_value
=
subscription_request
.
getPriceCurrencyValue
(),
temp_object
=
True
,
item_value
=
item
,
causality_value
=
subscription_request
,
# XXX .getCausalityValue(),
portal_type
=
'Subscription Change Request'
,
trade_condition_type
=
trade_condition_type
)
except
AssertionError
:
current_trade_condition
=
None
else
:
current_trade_condition
=
subscription_change_request
.
getSpecialiseValue
()
new_sale_trade_condition
=
None
if
(
current_trade_condition
is
None
):
# Create a dedicated trade condition for the customer
# to define free price
previous_title
=
subscription_request
.
getTitle
()
specialise_trade_condition
=
subscription_request
.
getSpecialiseValue
()
while
(
specialise_trade_condition
.
hasSourceSection
())
or
(
specialise_trade_condition
.
hasDestination
()):
previous_title
=
specialise_trade_condition
.
getTitle
()
specialise_trade_condition
=
specialise_trade_condition
.
getSpecialiseValue
()
new_sale_trade_condition
=
portal
.
sale_trade_condition_module
.
newContent
(
portal_type
=
'Sale Trade Condition'
,
specialise_value
=
specialise_trade_condition
,
title
=
'%s for %s'
%
(
previous_title
,
customer
.
getTitle
()),
destination_value
=
customer
,
destination_section_value
=
customer
,
source_project
=
subscription_request
.
getSourceProject
(),
source
=
subscription_request
.
getSource
(),
price_currency
=
subscription_request
.
getPriceCurrency
(),
trade_condition_type
=
trade_condition_type
,
activate_kw
=
activate_kw
)
new_sale_trade_condition
.
validate
()
subscription_request
.
activate
(
after_tag
=
activate_kw
[
'tag'
]).
SubscriptionRequest_changeFromPayableToFree
(
None
)
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Creating a free dedicated Trade Condition for the customer'
)
}
if
batch
:
return
new_sale_trade_condition
return
new_sale_trade_condition
.
Base_redirect
(
keep_items
=
keep_items
)
elif
(
current_trade_condition
.
getDestination
()
==
customer
.
getRelativeUrl
())
and
\
(
current_trade_condition
.
getSourceSection
(
None
)
is
None
):
# There is already a manual trade condition
# without any source section (free)
new_sale_trade_condition
=
current_trade_condition
subscription_change_request
=
subscription_request
.
getResourceValue
().
Resource_createSubscriptionRequest
(
customer
,
# [software_type, software_release],
subscription_request
.
getVariationCategoryList
(),
project
,
currency_value
=
subscription_request
.
getPriceCurrencyValue
(),
item_value
=
item
,
causality_value
=
subscription_request
,
portal_type
=
'Subscription Change Request'
,
trade_condition_type
=
trade_condition_type
)
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Creating a Subscription Change Request'
)
}
if
batch
:
return
subscription_change_request
return
subscription_change_request
.
Base_redirect
(
keep_items
=
keep_items
)
else
:
keep_items
=
{
'portal_status_level'
:
'error'
,
'portal_status_message'
:
Base_translateString
(
'This customer already has an incompatible dedicated Trade Condition'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
current_trade_condition
.
Base_redirect
(
keep_items
=
keep_items
)
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeFromPayableToFree.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</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>
dialog_id, activate_kw=None, REQUEST=None, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_changeFromPayableToFree
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.py
0 → 100644
View file @
edef233e
from
DateTime
import
DateTime
portal
=
context
.
getPortalObject
()
Base_translateString
=
portal
.
Base_translateString
subscription_request
=
context
from
zExceptions
import
Unauthorized
if
REQUEST
is
not
None
:
raise
Unauthorized
batch
=
(
dialog_id
is
None
)
if
activate_kw
is
None
:
activate_kw
=
{}
tag
=
activate_kw
.
get
(
'tag'
,
script
.
id
)
activate_kw
[
'tag'
]
=
tag
######################################################
# Prevent some mistakes
if
subscription_request
.
getSimulationState
()
!=
'submitted'
:
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'Can only change submitted subscription request'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
subscription_request
.
Base_redirect
(
keep_items
=
keep_items
)
current_price
=
subscription_request
.
getPrice
()
if
not
current_price
:
keep_items
=
{
'portal_status_level'
:
'warning'
,
'portal_status_message'
:
Base_translateString
(
'Can not make a free subscription to a payable one'
)
}
if
batch
:
raise
ValueError
(
keep_items
[
'portal_status_message'
])
return
subscription_request
.
Base_redirect
(
keep_items
=
keep_items
)
######################################################
# From payable to free
if
not
price
:
return
subscription_request
.
SubscriptionRequest_changeFromPayableToFree
(
dialog_id
)
######################################################
# Change price
portal_type
=
'Subscription Change Request'
subscription_change_request
=
portal
.
getDefaultModule
(
portal_type
).
newContent
(
portal_type
=
portal_type
,
causality_value
=
subscription_request
,
start_date
=
DateTime
(),
price
=
price
,
# Copy all other properties
destination
=
subscription_request
.
getDestination
(),
destination_section
=
subscription_request
.
getDestinationSection
(),
destination_decision
=
subscription_request
.
getDestinationDecision
(),
destination_project
=
subscription_request
.
getDestinationProject
(),
resource
=
subscription_request
.
getResource
(),
aggregate
=
subscription_request
.
getAggregate
(),
variation_category_list
=
subscription_request
.
getVariationCategoryList
(),
quantity_unit
=
subscription_request
.
getQuantityUnit
(),
quantity
=
subscription_request
.
getQuantity
(),
ledger
=
subscription_request
.
getLedger
(),
source
=
subscription_request
.
getSource
(),
source_section
=
subscription_request
.
getSourceSection
(),
source_project
=
subscription_request
.
getSourceProject
(),
price_currency
=
subscription_request
.
getPriceCurrency
(),
specialise
=
subscription_request
.
getSpecialise
(),
)
subscription_change_request
.
submit
()
keep_items
=
{
'portal_status_message'
:
Base_translateString
(
'Subscription Change Request created'
)
}
if
batch
:
return
subscription_change_request
return
subscription_change_request
.
Base_redirect
(
keep_items
=
keep_items
)
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_changeSlaposSubmittedPrice.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</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>
price, dialog_id, activate_kw=None, REQUEST=None, **kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_changeSlaposSubmittedPrice
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5 Form"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
SubscriptionRequest_changeSlaposSubmittedPrice
</string>
</value>
</item>
<item>
<key>
<string>
action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list>
<string>
your_price
</string>
</list>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string>
SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog
</string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_dialog
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Change Submitted Price
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/SkinTemplateItem/portal_skins/slapos_panel/SubscriptionRequest_viewChangeSlaposSubmittedPriceDialog/your_price.xml
0 → 100644
View file @
edef233e
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"FloatField"
module=
"Products.Formulator.StandardFields"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
your_price
</string>
</value>
</item>
<item>
<key>
<string>
message_values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
external_validator_failed
</string>
</key>
<value>
<string>
The input failed the external validator.
</string>
</value>
</item>
<item>
<key>
<string>
not_float
</string>
</key>
<value>
<string>
You did not enter a floating point number.
</string>
</value>
</item>
<item>
<key>
<string>
required_not_found
</string>
</key>
<value>
<string>
Input is required but no input given.
</string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
overrides
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
display_maxwidth
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
display_width
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
input_style
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
precision
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
autocomplete
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
display_maxwidth
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
display_width
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
input_style
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
input_type
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
precision
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAU=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
alternate_name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
css_class
</string>
</key>
<value>
<string>
figure
</string>
</value>
</item>
<item>
<key>
<string>
default
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string>
A typical price of a unit.
</string>
</value>
</item>
<item>
<key>
<string>
display_maxwidth
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
display_width
</string>
</key>
<value>
<int>
20
</int>
</value>
</item>
<item>
<key>
<string>
editable
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
external_validator
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
extra
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
input_style
</string>
</key>
<value>
<string>
-1 234.5
</string>
</value>
</item>
<item>
<key>
<string>
precision
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
required
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Price
</string>
</value>
</item>
<item>
<key>
<string>
whitespace_preserve
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
here/getPrice
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python: preferences.getPreference(\'preferred_money_quantity_field_width\', 10)
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python: preferences.getPreference(\'preferred_money_quantity_style\', \'-1 234.5\')
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"5"
aka=
"AAAAAAAAAAU="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
here/getPricePrecision
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_panel/bt/template_action_path_list
View file @
edef233e
...
@@ -96,6 +96,7 @@ Software Product | slapos_panel_view
...
@@ -96,6 +96,7 @@ Software Product | slapos_panel_view
Software Release Module | slapos_panel_view
Software Release Module | slapos_panel_view
Software Release | slapos_panel_view
Software Release | slapos_panel_view
Subscription Request Module | slapos_panel_view
Subscription Request Module | slapos_panel_view
Subscription Request | change_slapos_submitted_price
Subscription Request | jump_pay_my_slapos_sale_invoice_transaction
Subscription Request | jump_pay_my_slapos_sale_invoice_transaction
Subscription Request | slapos_panel_view
Subscription Request | slapos_panel_view
Support Request Module | slapos_panel_view
Support Request Module | slapos_panel_view
...
...
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