Commit 2af1186d authored by Alain Takoudjou's avatar Alain Takoudjou

Merge branch 'master' into master-dev

parents c37968ae 1ed2f20f

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

Changes
=======
1.3.15 (2015-12-08)
-------------------
* slapos.collect: Include disk usage report. Do not divide cpu_load by number of cpu cores.
1.3.14 (2015-10-27)
-------------------
* slapos.grid: firewall fix bugs
1.3.13 (2015-10-26)
-------------------
* slapos.grid: firewall accpet option to specify only list of ip address/wetwork to accept and reject.
1.3.12 (2015-10-15)
-------------------
* slapos.grid: add support for firewall configuration using firewalld for partition that use tap+route interface (for kvm cluster).
1.3.11 (2015-09-25)
-------------------
* slapos.grid: support shacache-ca-file and shadir-ca-file options.
1.3.10 (2015-04-28)
-------------------
1.3.9 (2015-02-20)
------------------
* slapos.format: allow to format additional list of folder for each partition to use as data storage location.
......
<?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_exchange</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_exchange</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>download</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>3.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Download</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}/Base_download</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -40,7 +40,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_hypermedia_preference</string> </value>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
......@@ -56,11 +56,11 @@
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>11.0</float> </value>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>SlapOS Hypermedia</string> </value>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
......@@ -77,7 +77,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/SystemPreference_viewSlapOSHypermedia</string> </value>
<value> <string>string:${object_url}/File_view</string> </value>
</item>
</dictionary>
</pickle>
......
<dtml-var table_0>.base_category_uid = <dtml-var "portal_categories.causality.getUid()">
AND <dtml-var table_1>.uid = <dtml-var table_0>.uid
AND <dtml-var table_1>.portal_type = 'Payment Transaction'
AND <dtml-var table_1>.simulation_state not in ('deleted', 'cancelled')
<dtml-var RELATED_QUERY_SEPARATOR>
<dtml-var table_0>.category_uid = <dtml-var query_table>.uid
......@@ -53,22 +53,6 @@ query_table="catalog"</string> </value>
<key> <string>max_rows_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-var table_0>.base_category_uid = <dtml-var "portal_categories.causality.getUid()">\n
AND <dtml-var table_1>.uid = <dtml-var table_0>.uid\n
AND <dtml-var table_1>.portal_type = \'Payment Transaction\'\n
AND <dtml-var table_1>.simulation_state not in (\'deleted\', \'cancelled\')\n
\n
<dtml-var RELATED_QUERY_SEPARATOR>\n
<dtml-var table_0>.category_uid = <dtml-var query_table>.uid\n
\n
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
......
<key_list>
<key>causality_payment_transaction_related_uid | category,catalog/uid/z_related_causality_payment_transaction</key>
<key>children_portal_type | catalog/portal_type/z_related_children</key>
<key>parent_specialise_uid | category,catalog/uid/z_related_parent_specialise</key>
</key_list>
\ No newline at end of file
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -54,6 +54,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......
......@@ -4,6 +4,7 @@
</portal_type>
<portal_type id="Consumption Document Module">
<item>Computer Consumption TioXML File</item>
<item>User Consumption HTML File</item>
</portal_type>
<portal_type id="Order Tool">
<item>SlapOS Accounting Quantity Updating Order Builder</item>
......
......@@ -18,4 +18,8 @@
<portal_type id="Software Instance">
<item>causality</item>
</portal_type>
<portal_type id="User Consumption HTML File">
<item>contributor</item>
<item>follow_up</item>
</portal_type>
</base_category_list>
\ No newline at end of file
......@@ -4,6 +4,7 @@
</portal_type>
<portal_type id="Consumption Document Module">
<item>Computer Consumption TioXML File</item>
<item>User Consumption HTML File</item>
</portal_type>
<portal_type id="Sale Invoice Transaction">
<item>Invoice Line</item>
......
......@@ -20,4 +20,7 @@
<portal_type id="Software Instance">
<item>InstanceAccountingSynchronisation</item>
</portal_type>
<portal_type id="User Consumption HTML File">
<item>SortIndex</item>
</portal_type>
</property_sheet_list>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>content_icon</string> </key>
<value> <string>file_icon.png</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addXMLObject</string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>document</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>User Consumption HTML File</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Base Type</string> </value>
</item>
<item>
<key> <string>searchable_text_method_id</string> </key>
<value>
<tuple>
<string>as_text</string>
</tuple>
</value>
</item>
<item>
<key> <string>searchable_text_property_id</string> </key>
<value>
<tuple>
<string>title</string>
<string>description</string>
<string>reference</string>
<string>version</string>
<string>short_title</string>
<string>subject_list</string>
<string>filename</string>
<string>source_project_title</string>
</tuple>
</value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>File</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -31,4 +31,8 @@
<type>Subscription Item Root Simulation Rule</type>
<workflow>edit_workflow, rule_validation_workflow</workflow>
</chain>
<chain>
<type>User Consumption HTML File</type>
<workflow>document_conversion_interaction_workflow, document_publication_workflow, document_security_interaction_workflow, edit_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Sale Packing List',
simulation_state='started',
causality_state='solved',
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),
method_id='Delivery_deliverStartedAggregatedSalePackingList',
activate_kw={'tag': tag},
)
context.activate(after_tag=tag).getId()
......@@ -48,20 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Sale Packing List\',\n
simulation_state=\'started\',\n
causality_state=\'solved\',\n
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),\n
method_id=\'Delivery_deliverStartedAggregatedSalePackingList\',\n
activate_kw={\'tag\': tag},\n
)\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
# XXX Filter directly the right open sale order
method_id='OpenSaleOrder_reindexIfIndexedBeforeLine',
portal_type="Open Sale Order",
children_portal_type="Open Sale Order Line",
activate_kw={'tag': tag},
)
context.activate(after_tag=tag).getId()
......@@ -48,21 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
\n
portal.portal_catalog.searchAndActivate(\n
# XXX Filter directly the right open sale order\n
method_id=\'OpenSaleOrder_reindexIfIndexedBeforeLine\',\n
portal_type="Open Sale Order",\n
children_portal_type="Open Sale Order Line",\n
activate_kw={\'tag\': tag},\n
)\n
\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
method_id='HostingSubscription_requestUpdateOpenSaleOrder',
portal_type="Hosting Subscription",
causality_state="diverged",
activate_kw={'tag': tag, 'priority': 2},
activity_count=10,
packet_size=1, # HostingSubscription_trigger_Person_storeOpenSaleOrderJournal
)
context.activate(after_tag=tag).getId()
......@@ -48,22 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
\n
portal.portal_catalog.searchAndActivate(\n
method_id=\'HostingSubscription_requestUpdateOpenSaleOrder\',\n
portal_type="Hosting Subscription",\n
causality_state="diverged",\n
activate_kw={\'tag\': tag, \'priority\': 2},\n
activity_count=10,\n
packet_size=1, # HostingSubscription_trigger_Person_storeOpenSaleOrderJournal\n
)\n
\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Open Sale Order',
validation_state='validated',
children_portal_type='Open Sale Order Line',
method_id='OpenSaleOrder_updatePeriod',
activate_kw={'tag': tag},
packet_size=1,
activity_count=100
)
context.activate(after_tag=tag).getId()
......@@ -48,21 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Open Sale Order\',\n
validation_state=\'validated\',\n
children_portal_type=\'Open Sale Order Line\',\n
method_id=\'OpenSaleOrder_updatePeriod\',\n
activate_kw={\'tag\': tag},\n
packet_size=1,\n
activity_count=100\n
)\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type=["Slave Instance", "Software Instance"],
causality_state="diverged",
method_id='Instance_solveInvoicingGeneration',
activate_kw={'tag': tag},
packet_size=1, # Separate calls to many transactions (calculation can take time)
activity_count=1,
)
context.activate(after_tag=tag).getId()
......@@ -48,22 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
\n
portal.portal_catalog.searchAndActivate(\n
portal_type=["Slave Instance", "Software Instance"],\n
causality_state="diverged",\n
method_id=\'Instance_solveInvoicingGeneration\',\n
activate_kw={\'tag\': tag},\n
packet_size=1, # Separate calls to many transactions (calculation can take time)\n
activity_count=1,\n
)\n
\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type="Computer Consumption TioXML File",
validation_state="submitted",
method_id='ComputerConsumptionTioXMLFile_solveInvoicingGeneration',
activity_count=1,
packet_size=1,
activate_kw={'tag': tag, 'priority': 5}
)
context.activate(after_tag=tag).getId()
......@@ -48,22 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
\n
portal.portal_catalog.searchAndActivate(\n
portal_type="Computer Consumption TioXML File",\n
validation_state="submitted",\n
method_id=\'ComputerConsumptionTioXMLFile_solveInvoicingGeneration\',\n
activity_count=1,\n
packet_size=1,\n
activate_kw={\'tag\': tag}\n
)\n
\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
if params is None:
params = {}
from DateTime import DateTime
from Products.ERP5Type.DateUtils import addToDate
from Products.ZSQLCatalog.SQLCatalog import Query
def getAccountingDate(accounting_date):
accounting_day = 25
if accounting_date.day() <= accounting_day:
accounting_date = addToDate(accounting_date, dict(month=-1))
diff = accounting_day - accounting_date.day()
accounting_date = addToDate(accounting_date, dict(day=diff))
return accounting_date
accounting_date = params.get('accounting_date', DateTime().earliestTime())
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Sale Packing List',
simulation_state='confirmed',
causality_state='solved',
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),
method_id='Delivery_startConfirmedAggregatedSalePackingList',
activate_kw={'tag': tag},
**{'delivery.start_date': Query(range="max",
**{'delivery.start_date': getAccountingDate(accounting_date)})}
)
context.activate(after_tag=tag).getId()
......@@ -48,43 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
if params is None:\n
params = {}\n
\n
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import addToDate\n
from Products.ZSQLCatalog.SQLCatalog import Query\n
\n
def getAccountingDate(accounting_date):\n
accounting_day = 25\n
if accounting_date.day() <= accounting_day:\n
accounting_date = addToDate(accounting_date, dict(month=-1))\n
diff = accounting_day - accounting_date.day()\n
accounting_date = addToDate(accounting_date, dict(day=diff))\n
return accounting_date\n
\n
accounting_date = params.get(\'accounting_date\', DateTime().earliestTime())\n
\n
portal = context.getPortalObject()\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Sale Packing List\',\n
simulation_state=\'confirmed\',\n
causality_state=\'solved\',\n
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),\n
method_id=\'Delivery_startConfirmedAggregatedSalePackingList\',\n
activate_kw={\'tag\': tag},\n
**{\'delivery.start_date\': Query(range="max",\n
**{\'delivery.start_date\': getAccountingDate(accounting_date)})}\n
)\n
context.activate(after_tag=tag).getId()\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
from DateTime import DateTime
from Products.ERP5Type.DateUtils import getClosestDate
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Sale Invoice Transaction',
simulation_state='confirmed',
causality_state='solved',
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),
method_id='Delivery_stopConfirmedAggregatedSaleInvoiceTransaction',
activate_kw={'tag': tag}
)
context.activate(after_tag=tag).getId()
......@@ -48,23 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate\n
\n
portal = context.getPortalObject()\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Sale Invoice Transaction\',\n
simulation_state=\'confirmed\',\n
causality_state=\'solved\',\n
specialise_uid=portal.restrictedTraverse(portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()).getUid(),\n
method_id=\'Delivery_stopConfirmedAggregatedSaleInvoiceTransaction\',\n
activate_kw={\'tag\': tag}\n
)\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
context.getPortalObject().portal_orders.slapos_aggregated_delivery_builder.build(
activate_kw={'tag': tag}
)
context.activate(after_tag=tag).getId()
......@@ -48,14 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>context.getPortalObject().portal_orders.slapos_aggregated_delivery_builder.build(\n
activate_kw={\'tag\': tag}\n
)\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
......
from DateTime import DateTime
portal = context.getPortalObject()
if context.getPortalType() != 'Sale Packing List':
raise TypeError('Incorrect delivery.')
isTransitionPossible = portal.portal_workflow.isTransitionPossible
if context.getSimulationState() == 'started' \
and len(context.checkConsistency()) == 0 \
and context.getCausalityState() == 'solved' \
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():
comment = 'Delivered by alarm as all actions in started state are ready.'
if isTransitionPossible(context, 'stop'):
context.stop(comment=comment)
if isTransitionPossible(context, 'deliver'):
context.deliver(comment=comment)
......@@ -48,24 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from DateTime import DateTime\n
portal = context.getPortalObject()\n
if context.getPortalType() != \'Sale Packing List\':\n
raise TypeError(\'Incorrect delivery.\')\n
isTransitionPossible = portal.portal_workflow.isTransitionPossible\n
if context.getSimulationState() == \'started\' \\\n
and len(context.checkConsistency()) == 0 \\\n
and context.getCausalityState() == \'solved\' \\\n
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():\n
comment = \'Delivered by alarm as all actions in started state are ready.\'\n
if isTransitionPossible(context, \'stop\'):\n
context.stop(comment=comment)\n
if isTransitionPossible(context, \'deliver\'):\n
context.deliver(comment=comment)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
from DateTime import DateTime
portal = context.getPortalObject()
if context.getPortalType() != 'Sale Packing List':
raise TypeError('Incorrect delivery.')
isTransitionPossible = portal.portal_workflow.isTransitionPossible
if context.getSimulationState() == 'confirmed' \
and len(context.checkConsistency()) == 0 \
and context.getCausalityState() == 'solved' \
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():
comment = 'Start by alarm as all actions in confirmed state are ready.'
date = DateTime().earliestTime()
context.edit(start_date=date, stop_date=date)
if isTransitionPossible(context, 'start'):
context.start(comment=comment)
......@@ -48,24 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from DateTime import DateTime\n
portal = context.getPortalObject()\n
if context.getPortalType() != \'Sale Packing List\':\n
raise TypeError(\'Incorrect delivery.\')\n
isTransitionPossible = portal.portal_workflow.isTransitionPossible\n
if context.getSimulationState() == \'confirmed\' \\\n
and len(context.checkConsistency()) == 0 \\\n
and context.getCausalityState() == \'solved\' \\\n
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():\n
comment = \'Start by alarm as all actions in confirmed state are ready.\'\n
date = DateTime().earliestTime()\n
context.edit(start_date=date, stop_date=date)\n
if isTransitionPossible(context, \'start\'):\n
context.start(comment=comment)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
portal = context.getPortalObject()
if context.getPortalType() != 'Sale Invoice Transaction':
raise TypeError('Incorrect delivery.')
isTransitionPossible = portal.portal_workflow.isTransitionPossible
if context.getSimulationState() == 'confirmed'\
and len(context.checkConsistency()) == 0\
and context.getCausalityState() == 'solved'\
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():
comment = 'Stopped by alarm as all actions in confirmed state are ready.'
if isTransitionPossible(context, 'start'):
context.start(comment=comment)
if isTransitionPossible(context, 'stop'):
context.stop(comment=comment)
......@@ -48,23 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
if context.getPortalType() != \'Sale Invoice Transaction\':\n
raise TypeError(\'Incorrect delivery.\')\n
isTransitionPossible = portal.portal_workflow.isTransitionPossible\n
if context.getSimulationState() == \'confirmed\'\\\n
and len(context.checkConsistency()) == 0\\\n
and context.getCausalityState() == \'solved\'\\\n
and context.getSpecialise() == portal.portal_preferences.getPreferredAggregatedSaleTradeCondition():\n
comment = \'Stopped by alarm as all actions in confirmed state are ready.\'\n
if isTransitionPossible(context, \'start\'):\n
context.start(comment=comment)\n
if isTransitionPossible(context, \'stop\'):\n
context.stop(comment=comment)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
from Products.ERP5Type.DateUtils import addToDate, getClosestDate
hosting_subscription = context
portal = context.getPortalObject()
workflow_item_list = portal.portal_workflow.getInfoFor(
ob=hosting_subscription,
name='history',
wf_id='instance_slap_interface_workflow')
start_date = None
for item in workflow_item_list:
start_date = item.get('time')
if start_date:
break
if start_date is None:
# Compatibility with old Hosting subscription
start_date = hosting_subscription.getCreationDate()
start_date = getClosestDate(target_date=start_date, precision='day')
return start_date
......@@ -48,36 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
from Products.ERP5Type.DateUtils import addToDate, getClosestDate\n
\n
hosting_subscription = context\n
portal = context.getPortalObject()\n
\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
start_date = None\n
for item in workflow_item_list:\n
start_date = item.get(\'time\')\n
if start_date:\n
break\n
\n
if start_date is None:\n
# Compatibility with old Hosting subscription\n
start_date = hosting_subscription.getCreationDate()\n
\n
start_date = getClosestDate(target_date=start_date, precision=\'day\')\n
\n
return start_date\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
from Products.ERP5Type.DateUtils import addToDate, getClosestDate
hosting_subscription = context
portal = context.getPortalObject()
start_date = context.HostingSubscription_calculateSubscriptionStartDate()
workflow_item_list = portal.portal_workflow.getInfoFor(
ob=hosting_subscription,
name='history',
wf_id='instance_slap_interface_workflow')
result_date = None
for item in workflow_item_list:
if item.get('slap_state') == 'destroy_requested':
end_date = item.get('time')
result_date = getClosestDate(target_date=end_date, precision='day')
if result_date <= end_date:
result_date = addToDate(result_date, to_add={'day': 1})
break
return result_date
......@@ -48,39 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
from Products.ERP5Type.DateUtils import addToDate, getClosestDate\n
\n
hosting_subscription = context\n
portal = context.getPortalObject()\n
\n
start_date = context.HostingSubscription_calculateSubscriptionStartDate()\n
\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
result_date = None\n
for item in workflow_item_list:\n
if item.get(\'slap_state\') == \'destroy_requested\':\n
end_date = item.get(\'time\')\n
result_date = getClosestDate(target_date=end_date, precision=\'day\')\n
if result_date <= end_date:\n
result_date = addToDate(result_date, to_add={\'day\': 1})\n
break\n
\n
return result_date\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
if context.getCausalityState() == 'diverged':
person = context.getDestinationSectionValue(portal_type="Person")
# Template document does not have person relation
if person is not None:
person.Person_storeOpenSaleOrderJournal()
# Person_storeOpenSaleOrderJournal should fix all divergent Hosting Subscription in one run
assert context.getCausalityState() == 'solved'
......@@ -48,22 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
if context.getCausalityState() == \'diverged\':\n
\n
person = context.getDestinationSectionValue(portal_type="Person")\n
# Template document does not have person relation\n
if person is not None:\n
person.Person_storeOpenSaleOrderJournal()\n
# Person_storeOpenSaleOrderJournal should fix all divergent Hosting Subscription in one run\n
assert context.getCausalityState() == \'solved\'\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
......
instance = context
portal = instance.getPortalObject()
portal_workflow = portal.portal_workflow
if portal_workflow.isTransitionPossible(instance, 'converge'):
instance.converge()
slap_state = instance.getSlapState()
if slap_state == 'draft':
# Nothing to do except converging
pass
else:
started = "start_requested"
stopped = "stop_requested"
destroyed = "destroy_requested"
assert slap_state in [started, stopped, destroyed]
previous_length = instance.getInvoicingSynchronizationPointer(1)
history_list = portal_workflow.getInfoFor(ob=instance, name='history', wf_id='instance_slap_interface_workflow')
history_length = len(history_list)
history_entry = history_list[previous_length-1]
# no divergence if no new history entry
if (history_length != 1):
assert previous_length != history_length
setup_quantity = 0
update_quantity = 0
destroy_quantity = 0
current_delivery = instance.getCausalityValue()
if current_delivery is None:
# No previous packing list, so, one setup should be created
# Drop all useless draft line
i_in_draft_state = True
i = 0
while i_in_draft_state:
checking_history_entry = history_list[i]
previous_state = checking_history_entry['slap_state']
if previous_state != 'draft':
i_in_draft_state = False
previous_length = i
else:
setup_quantity += 1
i += 1
if slap_state == destroyed:
# Check if previous pointer was already in destroyed state
previous_state = history_entry['slap_state']
if previous_state != destroyed:
# Let's create destroyed packing list
destroy_quantity = 1
# 1 = entry to set document in draft state
update_quantity = history_length - previous_length - setup_quantity - destroy_quantity
# Time to create the PL
delivery_template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredInstanceDeliveryTemplate())
delivery = delivery_template.Base_createCloneDocument(batch_mode=1)
hosting_subscription = instance.getSpecialiseValue(portal_type="Hosting Subscription")
person = hosting_subscription.getDestinationSectionValue(portal_type="Person")
delivery.edit(
title="%s API usage" % instance.getReference(),
destination=person.getRelativeUrl(),
destination_decision=person.getRelativeUrl(),
start_date=history_entry['time'],
stop_date=portal_workflow.getInfoFor(ob=instance, name='time', wf_id='instance_slap_interface_workflow'),
)
line_edit_kw = {
'aggregate_value_list': [instance, hosting_subscription],
}
if setup_quantity:
delivery_line_template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredInstanceSetupMovementTemplate())
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,
destination=delivery)
line.edit(
quantity=1,
title="%s setup %s" % (instance.getReference(), setup_quantity),
**line_edit_kw
)
if update_quantity > 0:
delivery_line_template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredInstanceUpdateMovementTemplate())
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,
destination=delivery)
line.edit(
quantity=update_quantity,
title="%s updated %i times" % (instance.getReference(), update_quantity),
**line_edit_kw
)
if destroy_quantity:
delivery_line_template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredInstanceDestroyMovementTemplate())
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,
destination=delivery)
line.edit(
quantity=destroy_quantity,
title="%s destroyed" % instance.getReference(),
**line_edit_kw
)
delivery.confirm()
delivery.start()
delivery.stop()
delivery.deliver()
delivery.startBuilding()
instance.edit(
invoicing_synchronization_pointer=history_length,
causality_value=delivery,
)
......@@ -48,133 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
instance = context\n
portal = instance.getPortalObject()\n
portal_workflow = portal.portal_workflow\n
\n
if portal_workflow.isTransitionPossible(instance, \'converge\'):\n
instance.converge()\n
\n
slap_state = instance.getSlapState()\n
\n
if slap_state == \'draft\':\n
# Nothing to do except converging\n
pass\n
else:\n
started = "start_requested"\n
stopped = "stop_requested"\n
destroyed = "destroy_requested"\n
assert slap_state in [started, stopped, destroyed]\n
\n
previous_length = instance.getInvoicingSynchronizationPointer(1)\n
history_list = portal_workflow.getInfoFor(ob=instance, name=\'history\', wf_id=\'instance_slap_interface_workflow\')\n
history_length = len(history_list)\n
history_entry = history_list[previous_length-1]\n
\n
# no divergence if no new history entry\n
if (history_length != 1):\n
assert previous_length != history_length\n
\n
setup_quantity = 0\n
update_quantity = 0\n
destroy_quantity = 0\n
\n
current_delivery = instance.getCausalityValue()\n
if current_delivery is None:\n
# No previous packing list, so, one setup should be created\n
# Drop all useless draft line\n
i_in_draft_state = True\n
i = 0\n
while i_in_draft_state:\n
checking_history_entry = history_list[i]\n
previous_state = checking_history_entry[\'slap_state\']\n
if previous_state != \'draft\':\n
i_in_draft_state = False\n
previous_length = i\n
else:\n
setup_quantity += 1\n
i += 1\n
\n
if slap_state == destroyed:\n
# Check if previous pointer was already in destroyed state\n
previous_state = history_entry[\'slap_state\']\n
if previous_state != destroyed:\n
# Let\'s create destroyed packing list\n
destroy_quantity = 1\n
\n
# 1 = entry to set document in draft state\n
update_quantity = history_length - previous_length - setup_quantity - destroy_quantity\n
\n
# Time to create the PL\n
delivery_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredInstanceDeliveryTemplate())\n
delivery = delivery_template.Base_createCloneDocument(batch_mode=1)\n
\n
hosting_subscription = instance.getSpecialiseValue(portal_type="Hosting Subscription")\n
person = hosting_subscription.getDestinationSectionValue(portal_type="Person")\n
\n
delivery.edit(\n
title="%s API usage" % instance.getReference(),\n
destination=person.getRelativeUrl(),\n
destination_decision=person.getRelativeUrl(),\n
start_date=history_entry[\'time\'],\n
stop_date=portal_workflow.getInfoFor(ob=instance, name=\'time\', wf_id=\'instance_slap_interface_workflow\'),\n
)\n
line_edit_kw = {\n
\'aggregate_value_list\': [instance, hosting_subscription],\n
}\n
\n
if setup_quantity:\n
delivery_line_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredInstanceSetupMovementTemplate())\n
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,\n
destination=delivery)\n
line.edit(\n
quantity=1,\n
title="%s setup %s" % (instance.getReference(), setup_quantity),\n
**line_edit_kw\n
)\n
\n
if update_quantity > 0:\n
delivery_line_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredInstanceUpdateMovementTemplate())\n
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,\n
destination=delivery)\n
line.edit(\n
quantity=update_quantity,\n
title="%s updated %i times" % (instance.getReference(), update_quantity),\n
**line_edit_kw\n
)\n
\n
if destroy_quantity:\n
delivery_line_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredInstanceDestroyMovementTemplate())\n
line = delivery_line_template.Base_createCloneDocument(batch_mode=1,\n
destination=delivery)\n
line.edit(\n
quantity=destroy_quantity,\n
title="%s destroyed" % instance.getReference(),\n
**line_edit_kw\n
)\n
\n
delivery.confirm()\n
delivery.start()\n
delivery.stop()\n
delivery.deliver()\n
delivery.startBuilding()\n
\n
instance.edit(\n
invoicing_synchronization_pointer=history_length,\n
causality_value=delivery,\n
)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
order = context
portal = context.getPortalObject()
indexation_timestamp = portal.portal_catalog(
uid=order.getUid(),
select_dict={'indexation_timestamp': None})[0].indexation_timestamp
line_list = portal.portal_catalog(
portal_type="Open Sale Order Line",
parent_uid=order.getUid(),
indexation_timestamp={'query': indexation_timestamp, 'range': 'nlt'},
limit=1)
if len(line_list):
order.activate().immediateReindexObject()
......@@ -48,28 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
order = context\n
portal = context.getPortalObject()\n
indexation_timestamp = portal.portal_catalog(\n
uid=order.getUid(),\n
select_dict={\'indexation_timestamp\': None})[0].indexation_timestamp\n
\n
line_list = portal.portal_catalog(\n
portal_type="Open Sale Order Line", \n
parent_uid=order.getUid(),\n
indexation_timestamp={\'query\': indexation_timestamp, \'range\': \'nlt\'},\n
limit=1)\n
\n
if len(line_list):\n
order.activate().immediateReindexObject()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
if context.getValidationState() == 'validated':
person = context.getDestinationDecisionValue(portal_type="Person")
if person is not None:
person.Person_storeOpenSaleOrderJournal()
......@@ -48,18 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
if context.getValidationState() == \'validated\':\n
person = context.getDestinationDecisionValue(portal_type="Person")\n
if person is not None:\n
person.Person_storeOpenSaleOrderJournal()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
......
select_kw = kwargs.copy()
select_kw.pop('portal_type', None)
select_kw.pop('delivery_relative_url_list', None)
from Products.ERP5Type.Document import newTempSimulationMovement
from Products.ZSQLCatalog.SQLCatalog import Query, NegatedQuery, ComplexQuery
portal = context.getPortalObject()
business_process_uid_list = [
portal.business_process_module.slapos_consumption_business_process.getUid(),
portal.business_process_module.slapos_subscription_business_process.getUid()]
specialise_uid_list = [q.getUid() for q in portal.portal_catalog(specialise_uid=business_process_uid_list,
portal_type='Sale Trade Condition')]
select_dict= {'default_aggregate_portal_type': None}
select_kw.update(
limit=50, # just take a bit
portal_type='Sale Packing List Line',
simulation_state='delivered',
parent_specialise_uid=specialise_uid_list,
select_dict=select_dict,
left_join_list=select_dict.keys(),
default_aggregate_portal_type=ComplexQuery(NegatedQuery(Query(default_aggregate_portal_type='Computer')),
Query(default_aggregate_portal_type=None), operator="OR"),
grouping_reference=None,
sort_on=(('modification_date', 'ASC'),) # the highest chance to find movement which can be delivered
)
movement_list = portal.portal_catalog(**select_kw)
specialise = portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()
temp_movement_list = []
id = 1
for movement in movement_list:
if movement.getGroupingReference() is not None:
continue
temp_movement = newTempSimulationMovement(
portal, movement.getRelativeUrl(),
quantity=movement.getQuantity(),
resource=movement.getResource(),
source=movement.getDestination(),
destination=movement.getDestination(),
source_section=movement.getSourceSection(),
destination_section=movement.getDestination(),
destination_decision=movement.getDestination(),
specialise=specialise,
price_currency=movement.getPriceCurrency()
)
if movement.getResource() == 'service_module/slapos_instance_subscription':
temp_movement.edit(price=0.83612040133800003)
else:
temp_movement.edit(price=0.0)
temp_movement_list.append(temp_movement)
id += 1
return temp_movement_list
......@@ -48,59 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>select_kw = kwargs.copy()\n
select_kw.pop(\'portal_type\', None)\n
select_kw.pop(\'delivery_relative_url_list\', None)\n
from Products.ERP5Type.Document import newTempSimulationMovement\n
portal = context.getPortalObject()\n
\n
business_process_uid_list = [\n
portal.business_process_module.slapos_consumption_business_process.getUid(),\n
portal.business_process_module.slapos_subscription_business_process.getUid()]\n
specialise_reference_list = [q.getReference() for q in portal.portal_catalog(specialise_uid=business_process_uid_list,\n
portal_type=\'Sale Trade Condition\')]\n
\n
select_kw.update(\n
limit=50, # just take a bit\n
portal_type=\'Sale Packing List Line\',\n
simulation_state=\'delivered\',\n
parent_specialise_reference=specialise_reference_list,\n
parent_specialise_portal_type=\'Sale Trade Condition\',\n
grouping_reference=None,\n
sort_on=((\'modification_date\', \'ASC\'),) # the highest chance to find movement which can be delivered\n
)\n
movement_list = portal.portal_catalog(**select_kw)\n
\n
specialise = portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()\n
temp_movement_list = []\n
id = 1\n
for movement in movement_list:\n
if movement.getGroupingReference() is not None:\n
continue\n
temp_movement = newTempSimulationMovement(\n
portal, movement.getRelativeUrl(),\n
quantity=movement.getQuantity(),\n
resource=movement.getResource(),\n
source=movement.getDestination(),\n
destination=movement.getDestination(),\n
source_section=movement.getSourceSection(),\n
destination_section=movement.getDestination(),\n
destination_decision=movement.getDestination(),\n
specialise=specialise,\n
price_currency=movement.getPriceCurrency()\n
)\n
if movement.getResource() == \'service_module/slapos_instance_subscription\':\n
temp_movement.edit(price=0.83612040133800003)\n
else:\n
temp_movement.edit(price=0.0)\n
temp_movement_list.append(temp_movement)\n
id += 1\n
\n
return temp_movement_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args, **kwargs</string> </value>
......
# beware: the configuration of OrderBuilder_generateSlapOSAggregatedMovementList shall
# provide small amounts of movements
person_delivery_mapping = {}
portal = context.getPortalObject()
specialise = portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()
for movement in movement_list:
person = movement.getDestinationValue()
try:
delivery = person_delivery_mapping[person]
except KeyError:
delivery = person.Person_getAggregatedDelivery()
if delivery is None or delivery.getSimulationState() != 'confirmed':
delivery = portal.sale_packing_list_module.newContent(
portal_type='Sale Packing List',
source=movement.getDestination(),
destination=movement.getDestination(),
source_section=movement.getSourceSection(),
destination_section=movement.getDestination(),
destination_decision=movement.getDestination(),
specialise=specialise,
price_currency=movement.getPriceCurrency()
)
delivery.confirm('New aggregated delivery.')
person.Person_setAggregatedDelivery(delivery)
person_delivery_mapping[person] = delivery
return person_delivery_mapping.values()
......@@ -48,37 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string># beware: the configuration of OrderBuilder_generateSlapOSAggregatedMovementList shall\n
# provide small amounts of movements\n
person_delivery_mapping = {}\n
portal = context.getPortalObject()\n
\n
specialise = portal.portal_preferences.getPreferredAggregatedSaleTradeCondition()\n
for movement in movement_list:\n
person = movement.getDestinationValue()\n
try:\n
delivery = person_delivery_mapping[person]\n
except KeyError:\n
delivery = person.Person_getAggregatedDelivery()\n
if delivery is None or delivery.getSimulationState() != \'confirmed\':\n
delivery = portal.sale_packing_list_module.newContent(\n
portal_type=\'Sale Packing List\',\n
source=movement.getDestination(),\n
destination=movement.getDestination(),\n
source_section=movement.getSourceSection(),\n
destination_section=movement.getDestination(),\n
destination_decision=movement.getDestination(),\n
specialise=specialise,\n
price_currency=movement.getPriceCurrency()\n
)\n
delivery.confirm(\'New aggregated delivery.\')\n
person.Person_setAggregatedDelivery(delivery)\n
person_delivery_mapping[person] = delivery\n
return person_delivery_mapping.values()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>movement_list, *args, **kwargs</string> </value>
......
from Products.ERP5Type.Message import translateString
payment_transaction = context
payment_transaction.immediateReindexObject() # in order to avoid selection in OrderBuilder_getAccountingTransactionLineListSlapOS
comment = translateString("Initialised by Order Builder.")
payment_transaction.confirm(comment=comment)
......@@ -48,15 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Message import translateString\n
payment_transaction = context\n
payment_transaction.immediateReindexObject() # in order to avoid selection in OrderBuilder_getAccountingTransactionLineListSlapOS\n
comment = translateString("Initialised by Order Builder.")\n
payment_transaction.confirm(comment=comment)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>related_simulation_movement_path_list=None, **kw</string> </value>
......
integration_site = context.getPortalObject().restrictedTraverse(
'portal_integrations/slapos_aggregated_delivery_integration_site')
person_id = context.getId().replace('-', '_')
try:
mapping = integration_site.getCategoryFromMapping('Causality/%s' % person_id, create_mapping_line=True, create_mapping=True)
except ValueError:
return None
return context.restrictedTraverse(mapping)
......@@ -48,19 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>integration_site = context.getPortalObject().restrictedTraverse(\n
\'portal_integrations/slapos_aggregated_delivery_integration_site\')\n
\n
person_id = context.getId().replace(\'-\', \'_\')\n
try:\n
mapping = integration_site.getCategoryFromMapping(\'Causality/%s\' % person_id, create_mapping_line=True, create_mapping=True)\n
except ValueError:\n
return None\n
return context.restrictedTraverse(mapping)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
integration_site = context.getPortalObject().restrictedTraverse(
'portal_integrations/slapos_aggregated_delivery_integration_site')
person_id = context.getId().replace('-', '_')
integration_site.Causality[person_id].setDestinationReference(delivery.getRelativeUrl())
......@@ -48,16 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>integration_site = context.getPortalObject().restrictedTraverse(\n
\'portal_integrations/slapos_aggregated_delivery_integration_site\')\n
\n
\n
person_id = context.getId().replace(\'-\', \'_\')\n
integration_site.Causality[person_id].setDestinationReference(delivery.getRelativeUrl())\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>delivery</string> </value>
......
from Products.ERP5Type.DateUtils import addToDate, getClosestDate
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_order_edit_kw = {
'effective_date': DateTime(),
'activate_kw': activate_kw,
}
if open_sale_order is None:
open_sale_order_template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredOpenSaleOrderTemplate())
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, hosting_subscription):
end_date = hosting_subscription.HostingSubscription_calculateSubscriptionStopDate()
if end_date is None:
# Be sure that start date is different from stop date
next_stop_date = hosting_subscription.getNextPeriodicalDate(hosting_subscription.HostingSubscription_calculateSubscriptionStartDate())
current_stop_date = next_stop_date
while next_stop_date < now:
# 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 = \
hosting_subscription.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_hosting_subscription_dict = {}
deleted_hosting_subscription_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
hosting_subscription = open_order_line.getAggregateValue(portal_type='Hosting Subscription')
assert current_start_date == hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()
# First check if the hosting subscription has been correctly simulated (this script may run only once per year...)
stop_date = calculateOpenOrderLineStopDate(open_order_line, hosting_subscription)
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 hosting_subscription.getSlapState() == 'destroy_requested':
# Line should be deleted
assert hosting_subscription.getCausalityState() == 'diverged'
delete_line_list.append(open_order_line.getId())
hosting_subscription.converge(comment="Last open order: %s" % open_order_line.getRelativeUrl())
deleted_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None
updated_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None
elif (hosting_subscription.getCausalityState() == 'diverged'):
hosting_subscription.converge(comment="Nothing to do on open order.")
updated_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None
# Time to check the open order line to add (remaining diverged Hosting
# Subscription normally)
for hosting_subscription in portal.portal_catalog(
portal_type='Hosting Subscription',
default_destination_section_uid=context.getUid(),
causality_state="diverged"):
hosting_subscription = hosting_subscription.getObject()
if hosting_subscription.getCausalityState() == 'diverged':
# Simply check that it has never been simulated
assert len(portal.portal_catalog(
portal_type='Open Sale Order Line',
default_aggregate_uid=hosting_subscription.getUid(),
limit=1)) == 0
# Let's add
add_line_list.append(hosting_subscription)
else:
# Should be in the list of lines to remove
assert (hosting_subscription.getRelativeUrl() in deleted_hosting_subscription_dict) or \
(hosting_subscription.getRelativeUrl() in updated_hosting_subscription_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 hosting_subscription in add_line_list:
open_sale_order_line = open_sale_order_line_template.Base_createCloneDocument(batch_mode=1,
destination=open_sale_order)
start_date = hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()
open_sale_order_line.edit(
activate_kw=activate_kw,
title=hosting_subscription.getTitle(),
start_date=start_date,
stop_date=calculateOpenOrderLineStopDate(open_sale_order_line, hosting_subscription),
aggregate_value=hosting_subscription,
)
storeWorkflowComment(open_sale_order_line, "Created for %s" % hosting_subscription.getRelativeUrl())
if (hosting_subscription.getSlapState() == 'destroy_requested'):
# Added line to delete immediately
delete_line_list.append(open_sale_order_line.getId())
hosting_subscription.converge(comment="Last open order: %s" % open_sale_order_line.getRelativeUrl())
else:
hosting_subscription.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)
......@@ -48,194 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from Products.ERP5Type.DateUtils import addToDate, getClosestDate\n
from DateTime import DateTime\n
\n
portal = context.getPortalObject()\n
now = DateTime()\n
person = context\n
tag = \'%s_%s\' % (person.getUid(), script.id)\n
activate_kw = {\'tag\': tag}\n
if portal.portal_activities.countMessageWithTag(tag) > 0:\n
# nothing to do\n
return\n
\n
def newOpenOrder(open_sale_order):\n
open_order_edit_kw = {\n
\'effective_date\': DateTime(),\n
\'activate_kw\': activate_kw,\n
}\n
if open_sale_order is None:\n
open_sale_order_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredOpenSaleOrderTemplate())\n
new_open_sale_order = open_sale_order_template.Base_createCloneDocument(batch_mode=1)\n
open_order_edit_kw.update({\n
\'destination\': person.getRelativeUrl(),\n
\'destination_decision\': person.getRelativeUrl(),\n
\'title\': "%s SlapOS Subscription" % person.getTitle(),\n
})\n
else:\n
new_open_sale_order = open_sale_order.Base_createCloneDocument(batch_mode=1)\n
open_sale_order.setExpirationDate(now, activate_kw=activate_kw)\n
new_open_sale_order.edit(**open_order_edit_kw)\n
new_open_sale_order.order(activate_kw=activate_kw)\n
new_open_sale_order.validate(activate_kw=activate_kw)\n
return new_open_sale_order\n
\n
def storeWorkflowComment(document, comment):\n
portal.portal_workflow.doActionFor(document, \'edit_action\', comment=comment)\n
\n
def calculateOpenOrderLineStopDate(open_order_line, hosting_subscription):\n
end_date = hosting_subscription.HostingSubscription_calculateSubscriptionStopDate()\n
if end_date is None: \n
# Be sure that start date is different from stop date\n
next_stop_date = hosting_subscription.getNextPeriodicalDate(hosting_subscription.HostingSubscription_calculateSubscriptionStartDate())\n
current_stop_date = next_stop_date\n
while next_stop_date < now:\n
# Return result should be < now, it order to provide stability in simulation (destruction if it happen should be >= now)\n
current_stop_date = next_stop_date\n
next_stop_date = \\\n
hosting_subscription.getNextPeriodicalDate(current_stop_date)\n
return addToDate(current_stop_date, to_add={\'second\': -1})\n
else:\n
stop_date = end_date\n
return stop_date\n
\n
# Prevent concurrent transaction to update the open order\n
context.serialize()\n
\n
# First, check the existing open order. Does some lines need to be removed, updated?\n
open_sale_order_list = portal.portal_catalog(\n
default_destination_uid=person.getUid(),\n
portal_type="Open Sale Order",\n
validation_state="validated",\n
limit=2,\n
)\n
open_sale_order_count = len(open_sale_order_list)\n
if open_sale_order_count == 0:\n
open_sale_order = None\n
elif open_sale_order_count == 1:\n
open_sale_order = open_sale_order_list[0].getObject()\n
else:\n
raise ValueError, "Too many open order \'%s\' found: %s" % (person.getRelativeUrl(), [x.path for x in open_sale_order_list])\n
\n
delete_line_list = []\n
add_line_list = []\n
\n
updated_hosting_subscription_dict = {}\n
deleted_hosting_subscription_dict = {}\n
\n
if open_sale_order is not None:\n
for open_order_line in open_sale_order.contentValues(\n
portal_type=\'Open Sale Order Line\'):\n
current_start_date = open_order_line.getStartDate()\n
current_stop_date = open_order_line.getStopDate()\n
\n
# Prevent mistakes\n
assert current_start_date is not None\n
assert current_stop_date is not None\n
assert current_start_date < current_stop_date\n
\n
hosting_subscription = open_order_line.getAggregateValue(portal_type=\'Hosting Subscription\')\n
assert current_start_date == hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()\n
\n
# First check if the hosting subscription has been correctly simulated (this script may run only once per year...)\n
stop_date = calculateOpenOrderLineStopDate(open_order_line, hosting_subscription)\n
if current_stop_date != stop_date:\n
# Bingo, new subscription to generate\n
open_order_line.edit(\n
stop_date=stop_date,\n
activate_kw=activate_kw)\n
storeWorkflowComment(open_order_line,\n
\'Stop date updated to %s\' % stop_date)\n
\n
if hosting_subscription.getSlapState() == \'destroy_requested\':\n
# Line should be deleted\n
assert hosting_subscription.getCausalityState() == \'diverged\'\n
delete_line_list.append(open_order_line.getId())\n
hosting_subscription.converge(comment="Last open order: %s" % open_order_line.getRelativeUrl())\n
deleted_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None\n
updated_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None\n
\n
elif (hosting_subscription.getCausalityState() == \'diverged\'):\n
hosting_subscription.converge(comment="Nothing to do on open order.")\n
updated_hosting_subscription_dict[hosting_subscription.getRelativeUrl()] = None\n
\n
# Time to check the open order line to add (remaining diverged Hosting\n
# Subscription normally)\n
for hosting_subscription in portal.portal_catalog(\n
portal_type=\'Hosting Subscription\',\n
default_destination_section_uid=context.getUid(),\n
causality_state="diverged"):\n
hosting_subscription = hosting_subscription.getObject()\n
if hosting_subscription.getCausalityState() == \'diverged\':\n
# Simply check that it has never been simulated\n
assert len(portal.portal_catalog(\n
portal_type=\'Open Sale Order Line\',\n
default_aggregate_uid=hosting_subscription.getUid(),\n
limit=1)) == 0\n
\n
# Let\'s add\n
add_line_list.append(hosting_subscription)\n
else:\n
# Should be in the list of lines to remove\n
assert (hosting_subscription.getRelativeUrl() in deleted_hosting_subscription_dict) or \\\n
(hosting_subscription.getRelativeUrl() in updated_hosting_subscription_dict)\n
\n
manual_archive = False\n
if (add_line_list):\n
# No need to create a new open order to add lines\n
if open_sale_order is None:\n
open_sale_order = newOpenOrder(None)\n
manual_archive = True\n
\n
open_order_explanation = ""\n
# Add lines\n
added_line_list = []\n
open_sale_order_line_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredOpenSaleOrderLineTemplate())\n
for hosting_subscription in add_line_list:\n
open_sale_order_line = open_sale_order_line_template.Base_createCloneDocument(batch_mode=1,\n
destination=open_sale_order)\n
start_date = hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()\n
open_sale_order_line.edit(\n
activate_kw=activate_kw,\n
title=hosting_subscription.getTitle(),\n
start_date=start_date,\n
stop_date=calculateOpenOrderLineStopDate(open_sale_order_line, hosting_subscription),\n
aggregate_value=hosting_subscription,\n
)\n
storeWorkflowComment(open_sale_order_line, "Created for %s" % hosting_subscription.getRelativeUrl())\n
if (hosting_subscription.getSlapState() == \'destroy_requested\'):\n
# Added line to delete immediately\n
delete_line_list.append(open_sale_order_line.getId())\n
hosting_subscription.converge(comment="Last open order: %s" % open_sale_order_line.getRelativeUrl())\n
else:\n
hosting_subscription.converge(comment="First open order: %s" % open_sale_order_line.getRelativeUrl())\n
added_line_list.append(open_sale_order_line.getId())\n
open_order_explanation += "Added %s." % str(added_line_list)\n
\n
new_open_sale_order = None\n
if (delete_line_list):\n
# All Verifications done. Time to clone/create open order\n
new_open_sale_order = newOpenOrder(open_sale_order)\n
if manual_archive == True:\n
open_sale_order.archive()\n
\n
open_order_explanation = ""\n
# Remove lines\n
new_open_sale_order.deleteContent(delete_line_list)\n
open_order_explanation += "Removed %s." % str(delete_line_list)\n
\n
storeWorkflowComment(new_open_sale_order, open_order_explanation)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
if kw.get('created_by_builder', 0):
return
context.newContent(portal_type='Sale Invoice Transaction Line',
id='income',)
context.newContent(portal_type='Sale Invoice Transaction Line',
id='receivable', )
context.newContent(portal_type='Sale Invoice Transaction Line',
id='collected_vat',)
......@@ -48,19 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>if kw.get(\'created_by_builder\', 0): \n
return\n
\n
context.newContent(portal_type=\'Sale Invoice Transaction Line\',\n
id=\'income\',)\n
context.newContent(portal_type=\'Sale Invoice Transaction Line\',\n
id=\'receivable\', )\n
context.newContent(portal_type=\'Sale Invoice Transaction Line\',\n
id=\'collected_vat\',)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args, **kw</string> </value>
......
invoice = context
total_price = invoice.getTotalPrice()
accounting_price = invoice.AccountingTransaction_getTotalCredit()
precision = invoice.getPriceCurrencyValue().getQuantityPrecision()
return round(total_price, precision) == round(accounting_price, precision)
......@@ -48,16 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>invoice = context\n
\n
total_price = invoice.getTotalPrice()\n
accounting_price = invoice.AccountingTransaction_getTotalCredit()\n
precision = invoice.getPriceCurrencyValue().getQuantityPrecision()\n
return round(total_price, precision) == round(accounting_price, precision)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
invoice = context
specialise = context.getPortalObject().portal_preferences.getPreferredAggregatedSaleTradeCondition()
if invoice.getSpecialise() != specialise:
raise TypeError('Only invoice specialised by %s shall be checked' % specialise)
if len(invoice.getCausalityRelatedList(portal_type='Cloud Contract')) > 0:
# Nothing to compare
return True
delivery_list = invoice.getCausalityValueList(portal_type='Sale Packing List')
amount = len(delivery_list)
if amount != 1:
raise TypeError('Wrong amount %s of related packing lists' % amount)
delivery = delivery_list[0]
return delivery.getTotalPrice(use='use/trade/sale') == context.getTotalPrice(use='use/trade/sale')
......@@ -48,31 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
invoice = context\n
specialise = context.getPortalObject().portal_preferences.getPreferredAggregatedSaleTradeCondition()\n
if invoice.getSpecialise() != specialise:\n
raise TypeError(\'Only invoice specialised by %s shall be checked\' % specialise)\n
\n
if len(invoice.getCausalityRelatedList(portal_type=\'Cloud Contract\')) > 0:\n
# Nothing to compare\n
return True\n
\n
\n
delivery_list = invoice.getCausalityValueList(portal_type=\'Sale Packing List\')\n
amount = len(delivery_list)\n
if amount != 1:\n
raise TypeError(\'Wrong amount %s of related packing lists\' % amount)\n
delivery = delivery_list[0]\n
\n
return delivery.getTotalPrice(use=\'use/trade/sale\') == context.getTotalPrice(use=\'use/trade/sale\')\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
specialise = context.getSpecialiseValue(portal_type='Sale Trade Condition')
amount_list = specialise.getAggregatedAmountList(context)
if len(amount_list) != 1:
return False
precision = context.getPriceCurrencyValue().getQuantityPrecision()
amount = amount_list[0]
total_price = amount.getTotalPrice()
invoice_tax = 0.
for line in context.getMovementList(context.getPortalInvoiceMovementTypeList()):
if line.getUse() == 'trade/tax':
invoice_tax += line.getTotalPrice()
return round(total_price, precision) == round(invoice_tax, precision)
......@@ -48,27 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>specialise = context.getSpecialiseValue(portal_type=\'Sale Trade Condition\')\n
amount_list = specialise.getAggregatedAmountList(context)\n
if len(amount_list) != 1:\n
return False\n
\n
precision = context.getPriceCurrencyValue().getQuantityPrecision()\n
\n
amount = amount_list[0]\n
\n
total_price = amount.getTotalPrice()\n
\n
invoice_tax = 0.\n
for line in context.getMovementList(context.getPortalInvoiceMovementTypeList()):\n
if line.getUse() == \'trade/tax\':\n
invoice_tax += line.getTotalPrice()\n
\n
return round(total_price, precision) == round(invoice_tax, precision)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
from DateTime import DateTime
restrictedTraverse = context.getPortalObject().restrictedTraverse
person = context.getDestination()
reference = context.getReference()
input_movement_list = [restrictedTraverse(q) for q in
related_simulation_movement_path_list
if restrictedTraverse(q).getDestination() == person]
for delivery_line in input_movement_list:
delivery_line.setGroupingReference(reference)
if context.getCausalityState() == 'draft':
context.startBuilding()
if context.getStartDate() is None:
context.setStartDate(DateTime().earliestTime())
......@@ -48,25 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from DateTime import DateTime\n
restrictedTraverse = context.getPortalObject().restrictedTraverse\n
person = context.getDestination()\n
reference = context.getReference()\n
input_movement_list = [restrictedTraverse(q) for q in\n
related_simulation_movement_path_list\n
if restrictedTraverse(q).getDestination() == person]\n
\n
for delivery_line in input_movement_list:\n
delivery_line.setGroupingReference(reference)\n
if context.getCausalityState() == \'draft\':\n
context.startBuilding()\n
\n
if context.getStartDate() is None:\n
context.setStartDate(DateTime().earliestTime())\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>related_simulation_movement_path_list, *args, **kwargs</string> </value>
......
......@@ -48,11 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>return {\'price\': 0.0}\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>default=None, movement=None, REQUEST=None, **kw</string> </value>
......
from Products.ERP5Type.DateUtils import addToDate
from Products.ZSQLCatalog.SQLCatalog import Query
from DateTime import DateTime
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Sale Invoice Transaction',
simulation_state='confirmed',
causality_state='solved',
creation_date=Query(creation_date=addToDate(DateTime(), to_add={'day': -20}), range="min"),
method_id='SaleInvoiceTransaction_generateResourceConsumptionDocument',
activity_count=1,
packet_size=1,
activate_kw={'tag': tag}
)
context.activate(after_tag=tag, priority=5).getId()
<?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>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_generateInvoiceResourceConsuptionDocument</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
For all software releases, upgrade the Average CPU and Memory Capacity
"""
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type="Software Release",
method_id="SotftwareRelease_updateCapacityQuantity",
)
......@@ -48,20 +48,6 @@
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
For all software releases, upgrade the Average CPU and Memory Capacity\n
"""\n
\n
portal = context.getPortalObject()\n
\n
portal.portal_catalog.searchAndActivate(\n
portal_type="Software Release",\n
method_id="SotftwareRelease_updateCapacityQuantity",\n
)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
......
from Products.ERP5Form.Report import ReportSection
result=[]
result.append(ReportSection(
path=context.getPhysicalPath(),
title=context.Base_translateString('Resource Consumption'),
form_id='WebSection_viewConsuptionReportList'))
return result
<?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>Base_getConsumptionListAsODSReport</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
cpu_resource = context.service_module.cpu_load_percent
memory_resource = context.service_module.memory_used
disk_resource = context.service_module.disk_used
return [(cpu_resource.getTitle(), cpu_resource.getUid()),
(disk_resource.getTitle(), disk_resource.getUid()),
(memory_resource.getTitle(), memory_resource.getUid())]
<?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>Base_getResourceServiceTitleUitList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from Products.ERP5Type.DateUtils import addToDate
from DateTime import DateTime
from Products.ZSQLCatalog.SQLCatalog import Query
portal = context.getPortalObject()
for key in ['portal_type', 'sort_on']:
if key in query_kw:
query_kw.pop(key)
#if not 'limit' in query_kw:
# query_kw['limit'] = 31 # limit is for one month by default
if grouping_reference is not None:
query_kw['grouping_reference'] = grouping_reference
sale_packing_list = portal.portal_catalog.getResultValue(
portal_type='Sale Packing List',
reference=grouping_reference,
)
if not sale_packing_list: # Strange cannot find this packing list ?
return []
min_date = sale_packing_list.getStopDate()
min_date = addToDate(min_date, dict(day=-31)) # Get max 31 (one accounting period) latest published consumption lines
query_kw['movement.start_date'] = Query(range="min",
**{'movement.start_date': min_date})
cpu_resource_uid = context.service_module.cpu_load_percent.getUid()
memory_resource_uid = context.service_module.memory_used.getUid()
consumption_dict = {}
def getPackingListLineForResource(resource_uid_list):
return portal.portal_catalog(
portal_type="Sale Packing List Line",
default_resource_uid = resource_uid_list,
**query_kw
)
def setDetailLine(packing_list_line):
start_date = DateTime(packing_list_line.getStartDate()).strftime('%Y/%m/%d')
hosting_reference = packing_list_line.getAggregateReference(
portal_type='Hosting Subscription')
hosting_title = packing_list_line.getAggregateTitle(
portal_type='Hosting Subscription')
software_instance = packing_list_line.getAggregateValue(
portal_type='Software Instance')
if software_instance is None:
# In case we found SPL line not aggregated to instance and hosting
return
instance_reference = software_instance.getReference()
#default_line = {'date': {'hosting_ref': ['hs_title', {'instance_ref': ['inst_title', ['res1', 'res2', 'resN'] ] } ] } }
if not start_date in consumption_dict:
# Add new date line
consumption_dict[start_date] = {hosting_reference:
[hosting_title,
{instance_reference:
[software_instance.getTitle(),
[0.0, 0.0]
]
}
]
}
# Add new Hosting line
if not hosting_reference in consumption_dict[start_date]:
consumption_dict[start_date][hosting_reference] = [hosting_title,
{instance_reference:
[software_instance.getTitle(),
[0.0, 0.0]
]
}
]
# Add new instance line
if not instance_reference in consumption_dict[start_date][hosting_reference][1]:
consumption_dict[start_date][hosting_reference][1][instance_reference] = [
software_instance.getTitle(), [0.0, 0.0]
]
if packing_list_line.getResourceUid() == cpu_resource_uid:
quantity = round(float(packing_list_line.getQuantity()), 3)
consumption_dict[start_date][hosting_reference][1][instance_reference][1][0] = quantity
elif packing_list_line.getResourceUid() == memory_resource_uid:
quantity = round( (float(packing_list_line.getQuantity())/1024.0), 3)
consumption_dict[start_date][hosting_reference][1][instance_reference][1][1] = quantity
# Add CPU_LOAD consumption details
for packing_list_line in getPackingListLineForResource([cpu_resource_uid,
memory_resource_uid]):
setDetailLine(packing_list_line)
consumption_list = []
for date in sorted(consumption_dict):
for hosting_key in sorted(consumption_dict[date]):
hosting_title, instance_dict = consumption_dict[date][hosting_key]
for instance_value_list in instance_dict.values():
instance_title, values = instance_value_list
consumption_list.append([date, hosting_title, instance_title, values[0], values[1]])
return consumption_list
<?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>grouping_reference=None, **query_kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getUserConsumptionDetailList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
if context.getPortalType() == "Computer":
# Get the Latest Sale Packing List
sale_packing_list_line = portal.portal_catalog.getResultValue(
portal_type='Sale Packing List Line',
simulation_state='delivered',
sort_on=[('movement.start_date', 'DESC')],
aggregate_uid=context.getUid(),
limit=1)
if sale_packing_list_line is not None:
sale_packing_list = sale_packing_list_line.getParent()
#request = context.getPortalObject().REQUEST
return sale_packing_list.Base_redirect('Base_viewListMode?proxy_form_id=SalePackingList_view&proxy_field_id=listbox')
# Redirect to web site to hide the indexation process
context.Base_redirect('view', keep_items={'portal_status_message':context.Base_translateString('No Consumption Report for this computer.')})
<?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>Base_jumpToViewLatestDayConsumption</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -35,7 +35,7 @@
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -86,14 +86,18 @@
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
<list>
<string>your_reportbox</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_preferred_hateoas_url</string>
<string>my_title</string>
<string>your_start_date</string>
<string>your_stop_date</string>
</list>
</value>
</item>
......@@ -108,7 +112,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SystemPreference_viewSlapOSHypermedia</string> </value>
<value> <string>Base_viewConsumptionReportListAsODSReport</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -116,11 +120,11 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>SystemPreference_viewSlapOSRestAPI</string> </value>
<value> <string>Folder_viewContentListAsODSReport</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
<value> <string>report_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
......@@ -132,7 +136,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>SlapOS Hypermedia</string> </value>
<value> <string>Consumption Report Document</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>your_status</string> </value>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -118,9 +118,7 @@
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -191,7 +189,7 @@
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string>inline clear</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
......@@ -239,7 +237,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Status</string> </value>
<value> <string>Title</string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
......@@ -259,20 +257,4 @@
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/SoftwareInstance_getStatus</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>report_method</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_reportbox</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>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_reportbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewReportFieldLibrary</string> </value>
</item>
<item>
<key> <string>report_method</string> </key>
<value> <string>Base_getConsumptionListAsODSReport</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment