Commit 9b0aef1a authored by Łukasz Nowak's avatar Łukasz Nowak

Use one alarm to manage open orders for person.

It minimises amount of Open Order versions and simplifies locking.

One Alarm to rule them all, One Alarm to find them,
One Alarm to bring them all and in the catalog bind them
parent 8eaf6e96
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_removeDestroyedOpenOrderLine</string> </value>
<value> <string>Alarm_updatePersonOpenOrder</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -22,35 +22,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_remove_destroyed_open_order_line</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
<value> <string>vifib_person_update_open_order</string> </value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
......@@ -71,19 +43,13 @@
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Removes Open Order Lines for freed partitions</string> </value>
<value> <string>Updates Persons\' Open Order to reflect changes</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_updateOpenSaleOrderStopDateOnLineList</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_update_open_sale_order_line</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>946684800.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Open Sale Order Line update</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>_body</string> </key>
<value> <string>stop_date = None\n
if params is not None:\n
stop_date = params.get(\'stop_date\')\n
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate, addToDate\n
\n
if stop_date is None:\n
# generate expected next month\n
stop_date = addToDate(getClosestDate(target_date=DateTime(), precision=\'month\', before=1), month=1)\n
\n
context.portal_catalog.searchAndActivate(\n
method_id=\'OpenSaleOrder_updateStopDate\',\n
activate_kw={\'tag\':tag},\n
method_kw={\'stop_date\': stop_date},\n
portal_type=\'Open Sale Order\',\n
validation_state=\'validated\')\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>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_updateOpenSaleOrderStopDateOnLineList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -55,8 +55,11 @@
if params is None:\n
params = {}\n
kw = {}\n
last_active_process = context.getLastActiveProcess()\n
\n
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate, addToDate\n
\n
last_active_process = context.getLastActiveProcess()\n
if last_active_process is not None and params.get(\'full\', False):\n
# fetch only objects modified since last alarm run\n
kw[\'indexation_timestamp\'] = \'>= %s\' % last_active_process.getStartDate().ISO()\n
......@@ -64,14 +67,16 @@ if last_active_process is not None and params.get(\'full\', False):\n
# register active process in order to have "windows" of last indexed objects\n
context.newActiveProcess()\n
\n
\n
params.setdefault(\'stop_date\', addToDate(getClosestDate(target_date=DateTime(), precision=\'month\', before=1), month=1))\n
\n
context.getPortalObject().portal_catalog.searchAndActivate(\n
method_id=\'SalePackingListLine_removeNotNeededOpenSaleOrderLine\',\n
portal_type=\'Sale Packing List Line\',\n
simulation_state=\'delivered\',\n
default_resource_uid=context.restrictedTraverse(context.getPortalObject().portal_preferences.getPreferredInstanceCleanupResource()).getUid(),\n
activity_kw={\'tag\': tag, \'priority\': 7},\n
**kw\n
method_id=\'Person_storeOpenOrderJournal\',\n
method_kw={\'indexation_timestamp\': kw.get(\'indexation_timestamp\'), \'tag\': tag, \'stop_date\': params[\'stop_date\']},\n
activate_kw={\'tag\': tag, \'priority\': 10},\n
portal_type=\'Person\'\n
)\n
\n
context.activate(after_tag=tag).getId()\n
......@@ -83,7 +88,7 @@ context.activate(after_tag=tag).getId()\n
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_removeDestroyedOpenOrderLine</string> </value>
<value> <string>Alarm_updatePersonOpenOrder</string> </value>
</item>
</dictionary>
</pickle>
......
<?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>_body</string> </key>
<value> <string>context.getDestinationDecisionValue().Person_updateOpenOrder(stop_date=stop_date)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>stop_date</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OpenSaleOrder_updateStopDate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -50,38 +50,79 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ZSQLCatalog.SQLCatalog import NegatedQuery, Query\n
<value> <string encoding="cdata"><![CDATA[
person = context\n
portal = context.getPortalObject()\n
if not(context.getPortalType() == \'Sale Packing List Line\' \n
and context.getSimulationState() == \'delivered\'\n
and context.getResource() == portal.portal_preferences.getPreferredInstanceCleanupResource()\n
and context.getAggregate(portal_type=\'Software Instance\') is not None):\n
return\n
all_delivered = True\n
for sale_packing_list_line in portal.portal_catalog(\n
portal_type="Sale Packing List Line", \n
default_aggregate_uid=context.getAggregateValue(portal_type=\'Software Instance\').getUid(),\n
simulation_state=NegatedQuery(Query(simulation_state=["delivered", "cancelled"])),\n
catalog = portal.portal_catalog\n
\n
cleanup_resource_uid = portal.restrictedTraverse(portal.portal_preferences.getPreferredInstanceCleanupResource()).getUid()\n
setup_resource_uid = portal.restrictedTraverse(portal.portal_preferences.getPreferredInstanceSetupResource()).getUid()\n
\n
person_uid = person.getUid()\n
\n
kw = {}\n
if indexation_timestamp is not None:\n
kw[\'indexation_timestamp\'] = ">= %s" % indexation_timestamp\n
\n
remove_hosting_list = []\n
add_kw_list = []\n
start_date_tuple_list = []\n
\n
for cleanup_line in catalog(\n
portal_type=\'Sale Packing List Line\',\n
default_resource_uid=cleanup_resource_uid,\n
simulation_state=\'delivered\',\n
**{\'movement.destination_uid\': person_uid}):\n
# **kw):\n
remove_hosting_list.append(cleanup_line.getAggregate(portal_type=\'Hosting Subscription\'))\n
\n
subscription_service_relative_url=portal.portal_preferences.getPreferredInstanceSubscriptionResource()\n
common_add_kw = dict(\n
portal_type="Open Sale Order Line",\n
quantity=1,\n
quantity_unit="unit/piece",\n
# XXX Hardcoded values\n
resource=subscription_service_relative_url,\n
price=portal.restrictedTraverse(subscription_service_relative_url).getSaleSupplyLineBasePrice()\n
)\n
for order in catalog(\n
portal_type=\'Sale Order\',\n
simulation_state=[\'planned\', \'confirmed\'],\n
default_destination_decision_uid=person_uid,\n
**kw\n
):\n
if sale_packing_list_line.getSimulationState() not in [\'delivered\', \'cancelled\']:\n
all_delivered = False\n
break\n
if all_delivered:\n
for open_order_line in portal.portal_catalog(\n
default_aggregate_uid=context.getAggregateValue(portal_type=\'Hosting Subscription\').getUid(),\n
portal_type=\'Open Sale Order Line\',\n
validation_state=\'validated\'):\n
if open_order_line.getValidationState() == \'validated\':\n
open_order_line.getParentValue().getDestinationDecisionValue().Person_updateOpenOrder(remove_id_list=[open_order_line.getId()])\n
</string> </value>
hosting_subscription = order.getMovementList()[0].getAggregate(portal_type=\'Hosting Subscription\')\n
add_kw = common_add_kw.copy()\n
add_kw.update(\n
title=portal.restrictedTraverse(hosting_subscription).getTitle(),\n
aggregate=hosting_subscription\n
)\n
add_kw_list.append(add_kw)\n
\n
for setup_line in catalog(\n
portal_type=\'Sale Packing List Line\',\n
default_resource_uid=setup_resource_uid,\n
simulation_state=[\'stopped\', \'delivered\'],\n
**{\'movement.destination_uid\': person_uid}\n
# **kw\n
):\n
# start date shall be stopped state reach\n
start_date = setup_line.getCreationDate()\n
start_date_tuple_list.append((setup_line.getAggregate(portal_type=\'Hosting Subscription\'), start_date))\n
\n
person.Person_updateOpenOrder(remove_hosting_list=remove_hosting_list, add_kw_list=add_kw_list, start_date_tuple_list=start_date_tuple_list, stop_date=stop_date)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>indexation_timestamp=None, tag=None, stop_date=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SalePackingListLine_removeNotNeededOpenSaleOrderLine</string> </value>
<value> <string>Person_storeOpenOrderJournal</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -54,17 +54,21 @@
from DateTime import DateTime\n
\n
person = context\n
portal = person.getPortalObject()\n
tag = \'%s_updateOpenOrder\' % person.getUid()\n
kw = {\'activate_kw\': {\'tag\': tag}}\n
activate_kw = {\'tag\': tag}\n
if portal.portal_activities.countMessageWithTag(tag) > 0:\n
# nothing to do\n
return\n
\n
if remove_id_list is None:\n
remove_id_list = []\n
if remove_hosting_list is None:\n
remove_hosting_list = []\n
if add_kw_list is None:\n
add_kw_list = []\n
if start_date_tuple_list is None:\n
start_date_tuple_list = []\n
\n
person = context\n
portal = person.getPortalObject()\n
previous_open_sale_order = portal.portal_catalog.getResultValue(\n
default_destination_section_uid=person.getUid(),\n
portal_type="Open Sale Order",\n
......@@ -83,24 +87,34 @@ if previous_open_sale_order is None:\n
price_currency=\'currency_module/EUR\',\n
specialise=\'sale_trade_condition_module/vifib_trade_condition\',\n
title="ViFiB Open Order",\n
**kw)\n
for remove_id in remove_id_list:\n
if open_sale_order is None:\n
open_sale_order = previous_open_sale_order.Base_createCloneDocument(batch_mode=1)\n
open_sale_order.deleteContent(remove_id)\n
if add_kw is not None:\n
add_tag = add_kw.pop(\'tag\', None)\n
add_kw.update(kw)\n
if open_sale_order is None:\n
open_sale_order = previous_open_sale_order.Base_createCloneDocument(batch_mode=1)\n
open_sale_order.newContent(**add_kw)\n
if add_tag is not None:\n
# lock by passed tag\n
open_sale_order.activate(tag=add_tag, after_tag=kw[\'activate_kw\'][\'tag\']).getId()\n
activate_kw=activate_kw)\n
\n
hosting_subscription_mapping = {}\n
if previous_open_sale_order is not None:\n
for open_sale_order_line in previous_open_sale_order.contentValues(portal_type=\'Open Sale Order Line\'):\n
hosting_subscription_mapping[open_sale_order_line.getAggregate(portal_type=\'Hosting Subscription\')] = open_sale_order_line.getId()\n
\n
just_added_hosting_kw = {}\n
for add_kw in add_kw_list:\n
add_kw[\'activate_kw\'] = activate_kw\n
existing = portal.portal_catalog.countResults(portal_type=\'Open Sale Order Line\', default_aggregate_uid=portal.restrictedTraverse(add_kw[\'aggregate\']).getUid())[0][0] > 0\n
if add_kw[\'aggregate\'] not in hosting_subscription_mapping and not existing:\n
if open_sale_order is None:\n
open_sale_order = previous_open_sale_order.Base_createCloneDocument(batch_mode=1)\n
id = open_sale_order.newContent(**add_kw).getId()\n
hosting_subscription_mapping[add_kw[\'aggregate\']] = id\n
just_added_hosting_kw[add_kw[\'aggregate\']] = 1\n
\n
if open_sale_order is not None:\n
for start_date_tuple in start_date_tuple_list:\n
if start_date_tuple[0] in hosting_subscription_mapping:\n
open_sale_order[hosting_subscription_mapping[start_date_tuple[0]]].setStartDate(start_date_tuple[1])\n
\n
if stop_date is not None:\n
# check if needed to update\n
need_update = False\n
for line in previous_open_sale_order.contentValues(portal_type=\'Open Sale Order Line\'):\n
order = previous_open_sale_order or open_sale_order\n
for line in order.contentValues(portal_type=\'Open Sale Order Line\'):\n
if line.getStopDate() < stop_date:\n
need_update = True\n
break\n
......@@ -109,20 +123,37 @@ if stop_date is not None:\n
open_sale_order = previous_open_sale_order.Base_createCloneDocument(batch_mode=1)\n
for line in open_sale_order.contentValues(portal_type=\'Open Sale Order Line\'):\n
if line.getStopDate() < stop_date:\n
line.setStopDate(stop_date, **kw)\n
line.setStopDate(stop_date, activate_kw=activate_kw)\n
\n
for remove_hosting in remove_hosting_list:\n
if remove_hosting in just_added_hosting_kw:\n
# just added, cannot remove yet\n
continue\n
remove_id = hosting_subscription_mapping.get(remove_hosting)\n
if remove_id is not None:\n
if open_sale_order is not None:\n
line = open_sale_order[remove_id]\n
elif previous_open_sale_order is not None:\n
line = previous_open_sale_order[remove_id]\n
if line.getStartDate() is not None and line.getStopDate() is not None and line.getStartDate() < line.getStopDate():\n
if open_sale_order is None:\n
open_sale_order = previous_open_sale_order.Base_createCloneDocument(batch_mode=1)\n
open_sale_order.deleteContent(remove_id)\n
hosting_subscription_mapping.pop(remove_hosting)\n
\n
if previous_open_sale_order is not None and open_sale_order is not None:\n
previous_open_sale_order.setExpirationDate(now, **kw)\n
previous_open_sale_order.setExpirationDate(now, activate_kw=activate_kw)\n
if open_sale_order is not None:\n
open_sale_order.setEffectiveDate(now, **kw)\n
open_sale_order.order(**kw)\n
open_sale_order.validate(**kw)\n
open_sale_order.setEffectiveDate(now, activate_kw=activate_kw)\n
open_sale_order.order(activate_kw=activate_kw)\n
open_sale_order.validate(activate_kw=activate_kw)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>remove_id_list=None, add_kw=None, stop_date=None</string> </value>
<value> <string>remove_hosting_list=None, add_kw_list=None, stop_date=None, start_date_tuple_list=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
623
\ No newline at end of file
624
\ No newline at end of file
......@@ -10,8 +10,7 @@ portal_alarms/vifib_desactivate_dead_computer
portal_alarms/vifib_destroy_non_instanciated_partition
portal_alarms/vifib_lock_person
portal_alarms/vifib_lock_software_instance
portal_alarms/vifib_remove_destroyed_open_order_line
portal_alarms/vifib_person_update_open_order
portal_alarms/vifib_trigger_build
portal_alarms/vifib_unlock_person
portal_alarms/vifib_unlock_software_instance
portal_alarms/vifib_update_open_sale_order_line
\ No newline at end of file
portal_alarms/vifib_unlock_software_instance
\ No newline at end of file
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