Commit 9b2c1763 authored by Jean-Paul Smets's avatar Jean-Paul Smets

Global Udate to Latest Coramy Optimizations


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@441 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent de62f3e8
...@@ -60,7 +60,9 @@ class Invoice(ERP5Invoice): ...@@ -60,7 +60,9 @@ class Invoice(ERP5Invoice):
, PropertySheet.Movement , PropertySheet.Movement
, PropertySheet.Amount , PropertySheet.Amount
, PropertySheet.Reference , PropertySheet.Reference
, PropertySheet.TradeCondition
, PropertySheet.PaymentCondition , PropertySheet.PaymentCondition
, PropertySheet.Comment
) )
# Factory Type Information # Factory Type Information
......
...@@ -155,4 +155,24 @@ Un item sert a assurer la tracabilite des choses dans ERP5.""" ...@@ -155,4 +155,24 @@ Un item sert a assurer la tracabilite des choses dans ERP5."""
sub_quantity = 0 sub_quantity = 0
for sub_item in sub_item_list : for sub_item in sub_item_list :
sub_quantity += sub_item.getQuantity() sub_quantity += sub_item.getQuantity()
return self.getQuantity() - sub_quantity return self.getQuantity() - sub_quantity
\ No newline at end of file
security.declareProtected(Permissions.ModifyPortalContent, 'getLastLocationTitle')
def getLastLocationTitle(self):
"""
Returns the last location of this item or empty string
"""
related_movement_list = self.PieceTissu_zGetAggregateRelatedMovementList()
if len(related_movement_list) > 0 :
last_movement = related_movement_list[0]
quantity = last_movement.quantity
inventory = last_movement.inventory
if inventory is not None :
last_location_title = last_movement.destination_title
elif quantity >= 0 :
last_location_title = last_movement.destination_title
else :
last_location_title = ''
return last_location_title
else :
return ''
...@@ -168,8 +168,14 @@ un modele...""" ...@@ -168,8 +168,14 @@ un modele..."""
""" """
return PRI for Modle return PRI for Modle
""" """
for pri in self.contentValues({'portal_type': 'Set Mapped Value'}): for pri in self.contentValues(filter={'portal_type': 'Set Mapped Value'}):
if 'pri' in pri.getMappedValuePropertyList(): if 'pri' in pri.getMappedValuePropertyList():
if pri.test(context): if pri.test(context):
return pri.getProperty('pri') return pri.getProperty('pri')
return None return None
def _updateIndustrialPrice(self):
pass
#self.modele_compute_pri(batch_mode=1)
...@@ -7,4 +7,20 @@ ...@@ -7,4 +7,20 @@
##parameters= ##parameters=
##title= ##title=
## ##
return context organisation_list = context.object_action_list(selection_name='organisations_selection')
request = context.REQUEST
tab = '\t'
cr = '\n'
export = ''
del_list = []
for modele_item in organisation_list :
ligne_modele = ''
modele=modele_item.getObject()
if int(modele.getId()) >= 726 :
del_list.append(modele.getId())
context.getPortalObject().organisation.deleteContent(del_list)
return len(del_list)
...@@ -7,22 +7,25 @@ ...@@ -7,22 +7,25 @@
##parameters= ##parameters=
##title= ##title=
## ##
selection = context.portal_selections.getSelectionFor('purchase_packing_list_selection',REQUEST=context.REQUEST) # Collect movements in Zero Stock applied rule
delivery_list = selection(context=context) zs_movement_list = [context.portal_simulation.zero_stock['modele-137H401_coloris-modele-137H401-1_taille-adulte-52']]
request = context.REQUEST
for delivery_item in delivery_list: # keep only movements with a Modele resource
delivery = delivery_item.getObject() movement_list = []
for movement in zs_movement_list :
try :
if movement.getResourceValue().getPortalType() == 'Modele' :
movement_list.append(movement)
except :
pass
if delivery is not None : # Parse movements into a root group
order_list = delivery.getCausalityValueList() root_group = context.portal_simulation.collectMovement(movement_list)
if len(order_list) > 0 : order_list = context.portal_simulation.buildOrderList(root_group)
order = order_list[0]
# what's the gestionaire of this order
user_name = ''
# are we on a sales order or puchase order ?
if order.getPortalType() == 'Purchase Order' :
user_name = order.getDestinationAdministrationPersonTitle().replace(' ','_')
delivery.assign_gestionaire_designe_roles(user_name = user_name)
return 'fait' # update produced orders
for order in order_list:
order.autoPlan()
order.purchase_order_apply_condition()
return "fait"
<dtml-comment> <dtml-comment>
title: title:
connection_id:MySQL connection_id:MySQL
max_rows:1000 max_rows:100000
max_cache:100 max_cache:0
cache_time:0 cache_time:0
class_name: class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params>section <params></params>
strict_membership</params>
SELECT DISTINCT SELECT DISTINCT
movement.resource_uid, movement.resource_uid,
catalog.relative_url AS resource_relative_url,
movement.variation_text movement.variation_text
FROM FROM
movement, stock, catalog as section, category movement LEFT JOIN catalog ON (catalog.uid = movement.resource_uid)
WHERE \ No newline at end of file
stock.uid = movement.uid
AND stock.section_uid = section.uid
AND section.uid = category.category_uid
AND category.base_category_uid = <dtml-sqlvar "portal_categories.group.getUid()" type="int">
AND section.relative_url = <dtml-sqlvar section type="string">
<dtml-if strict_membership>AND category.strict_membership=1</dtml-if>
\ No newline at end of file
...@@ -8,16 +8,18 @@ class_name: ...@@ -8,16 +8,18 @@ class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params></params> <params></params>
# Host:
# Database: test
# Table: 'stock'
#
CREATE TABLE `message` ( CREATE TABLE `message` (
`uid` int(11) NOT NULL auto_increment,
`path` VARCHAR(255), `path` VARCHAR(255),
`method_id` VARCHAR(40), `method_id` VARCHAR(40),
`processing_node` INT DEFAULT -1,
`processing` INT DEFAULT 0,
`priority` INT DEFAULT 0,
`message` BLOB, `message` BLOB,
`processing_node` INT DEFAULT NULL, PRIMARY KEY (`uid`),
KEY `path` (`path`), KEY `path` (`path`),
KEY `processing_node` (`processing_node`),
KEY `method_id` (`method_id`), KEY `method_id` (`method_id`),
) TYPE = InnoDB; KEY `processing_node` (`processing_node`),
\ No newline at end of file KEY `processing` (`processing`),
KEY `priority` (`priority`),
) TYPE = InnoDB;
...@@ -7,11 +7,9 @@ cache_time:0 ...@@ -7,11 +7,9 @@ cache_time:0
class_name: class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params>path <params>uid:list</params>
method_id</params>
DELETE FROM DELETE FROM
message message
WHERE WHERE
path = <dtml-sqlvar path type="string"> <dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else> OR </dtml-if>
<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if> </dtml-in>
\ No newline at end of file
\ No newline at end of file
<dtml-comment> <dtml-comment>
title: title:
connection_id:MySQL connection_id:MySQL
max_rows:1000 max_rows:1
max_cache:100 max_cache:0
cache_time:0 cache_time:0
class_name: class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params>path <params>uid</params>
method_id
processing_node</params>
UPDATE message UPDATE message
SET processing_node=<dtml-sqlvar processing_node type="int"> SET processing=1
WHERE WHERE
path = <dtml-sqlvar path type="string"> <dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else>
<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if> OR </dtml-if></dtml-in>
\ No newline at end of file \ No newline at end of file
...@@ -7,8 +7,14 @@ cache_time:0 ...@@ -7,8 +7,14 @@ cache_time:0
class_name: class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params></params> <params>processing_node
priority</params>
SELECT * FROM SELECT * FROM
message message
WHERE WHERE
processing_node is NULL processing <> 1
\ No newline at end of file <dtml-if processing_node> AND processing_node = <dtml-sqlvar processing_node type="int"></dtml-if>
<dtml-if priority> AND priority = <dtml-sqlvar priority type="int"> </dtml-if>
ORDER BY
priority
\ No newline at end of file
...@@ -8,12 +8,16 @@ class_name: ...@@ -8,12 +8,16 @@ class_name:
class_file: class_file:
</dtml-comment> </dtml-comment>
<params>path <params>path
method_id</params> method_id
processing_node
priority</params>
SELECT * FROM SELECT * FROM
message message
<dtml-if "path or method_id">
WHERE WHERE
<dtml-if path> path = <dtml-sqlvar path type="string"></dtml-if> processing <> 1
<dtml-if processing_node>AND processing_node = <dtml-sqlvar processing_node type="int"> </dtml-if>
<dtml-if priority>AND priority = <dtml-sqlvar priority type="int"> </dtml-if>
<dtml-if path>AND path = <dtml-sqlvar path type="string"></dtml-if>
<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if> <dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
</dtml-if> GROUP BY
path, method_id, processing_node, processing
\ No newline at end of file \ No newline at end of file
...@@ -9,7 +9,13 @@ class_file: ...@@ -9,7 +9,13 @@ class_file:
</dtml-comment> </dtml-comment>
<params>path <params>path
method_id method_id
message</params> message
priority</params>
INSERT INTO message INSERT INTO message
VALUES SET
(<dtml-sqlvar path type="string">,<dtml-sqlvar method_id type="string">,<dtml-sqlvar message type="string">,NULL); path = <dtml-sqlvar path type="string">,
\ No newline at end of file method_id = <dtml-sqlvar method_id type="string">,
processing_node = -1,
processing = -1,
priority = <dtml-sqlvar priority type="int">,
message = <dtml-sqlvar message type="string">
\ No newline at end of file
...@@ -30,6 +30,7 @@ try: ...@@ -30,6 +30,7 @@ try:
action_list = o.portal_workflow.getActionsFor(o) action_list = o.portal_workflow.getActionsFor(o)
action_list = filter(lambda x:x.has_key('id'), action_list ) action_list = filter(lambda x:x.has_key('id'), action_list )
action_id_list = map(lambda x:x['id'], action_list) action_id_list = map(lambda x:x['id'], action_list)
# If the user is not allowed to do this transition, it will not be in action_list
if workflow_action in action_id_list: if workflow_action in action_id_list:
o.portal_workflow.doActionFor( o.portal_workflow.doActionFor(
o, o,
......
...@@ -11,7 +11,7 @@ class_file:zsqlbrain.py ...@@ -11,7 +11,7 @@ class_file:zsqlbrain.py
variante_id_list="" variante_id_list=""
sort_on sort_on
portal_type</params> portal_type</params>
SELECT DISTINCT catalog.id, catalog.relative_url, catalog.path, catalog.Description, catalog.simulation_state, catalog.default_destination_title SELECT DISTINCT catalog.id, catalog.uid, catalog.relative_url, catalog.path, catalog.Description, catalog.simulation_state, catalog.default_destination_title
FROM catalog, catalog AS line FROM catalog, catalog AS line
<dtml-if expr="_.len(resource_id_list)>0"> <dtml-if expr="_.len(resource_id_list)>0">
, catalog AS resource , catalog AS resource
......
...@@ -20,6 +20,10 @@ AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid() ...@@ -20,6 +20,10 @@ AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()
LEFT JOIN stock LEFT JOIN stock
ON (stock.uid = category.uid) ON (stock.uid = category.uid)
LEFT JOIN movement
ON (movement.uid = category.uid)
WHERE item.portal_type = "Piece Tissu" WHERE item.portal_type = "Piece Tissu"
AND stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()"> AND stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()">
AND stock.quantity < 0 AND stock.quantity < 0
\ No newline at end of file AND movement.inventory IS NULL
\ No newline at end of file
...@@ -17,6 +17,23 @@ SELECT DISTINCT ...@@ -17,6 +17,23 @@ SELECT DISTINCT
item.uid, item.id, item.path, item.Description, item.simulation_state, item.default_destination_title item.uid, item.id, item.path, item.Description, item.simulation_state, item.default_destination_title
FROM FROM
catalog AS item catalog AS item
LEFT JOIN category
ON (category.category_uid=item.uid
AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">)
LEFT JOIN stock
ON (stock.uid = category.uid)
LEFT JOIN movement
ON (movement.uid = category.uid)
LEFT JOIN movement AS next_movement
ON (next_movement.resource_uid = movement.resource_uid
AND next_movement.variation_text = movement.variation_text
AND next_movement.start_date > movement.start_date
AND not (next_movement.inventory is NULL))
<dtml-if expr="_.len(resource_id_list)>0"> <dtml-if expr="_.len(resource_id_list)>0">
, catalog AS resource , catalog AS resource
, category AS cat1 , category AS cat1
...@@ -26,9 +43,15 @@ FROM ...@@ -26,9 +43,15 @@ FROM
, category AS cat2 , category AS cat2
</dtml-if> </dtml-if>
WHERE item.portal_type = "Piece Tissu" WHERE
<dtml-in PieceTissu_searchConsumedList>AND item.uid <> <dtml-sqlvar uid type="int"> item.portal_type = "Piece Tissu"
AND stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()">
AND ( stock.quantity >= 0
OR (stock.quantity < 0
AND not (movement.inventory is NULL) ) )
<dtml-in PieceTissu_searchConsumedList>AND item.uid <> <dtml-sqlvar uid type="int">
</dtml-in> </dtml-in>
AND next_movement.uid is NULL
<dtml-if expr="_.len(resource_id_list)>0"> <dtml-if expr="_.len(resource_id_list)>0">
AND ( resource.id LIKE "<dtml-var expr="resource_id_list[0]">" AND ( resource.id LIKE "<dtml-var expr="resource_id_list[0]">"
......
<dtml-comment> <dtml-comment>
title: title:
connection_id:MySQL connection_id:MySQL
max_rows:1000 max_rows:750
max_cache:100 max_cache:100
cache_time:0 cache_time:0
class_name:ZSQLBrain class_name:ZSQLBrain
...@@ -15,17 +15,15 @@ resource_uid</params> ...@@ -15,17 +15,15 @@ resource_uid</params>
SELECT SELECT
catalog.* catalog.*
FROM FROM
catalog, movement, category, stock, catalog as movement_c catalog, movement, category, stock
WHERE WHERE
movement.uid = category.uid movement.uid = category.uid
AND category.category_uid = catalog.uid
AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">
AND stock.uid = movement.uid AND stock.uid = movement.uid
AND movement.is_accountable = 1 AND movement.is_accountable = 1
AND movement.resource_uid = <dtml-sqlvar resource_uid type="int"> AND movement.resource_uid = <dtml-sqlvar resource_uid type="int">
AND movement_c.uid = category.uid
AND category.category_uid = catalog.uid
AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">
AND movement.delivery_uid = <dtml-sqlvar explanation_uid type="int"> AND movement.delivery_uid = <dtml-sqlvar explanation_uid type="int">
AND movement.variation_text = <dtml-sqlvar variation_text type="string"> AND movement.variation_text = <dtml-sqlvar variation_text type="string">
AND stock.node_uid = <dtml-sqlvar node_uid type="int"> AND stock.node_uid = <dtml-sqlvar node_uid type="int">
AND stock.section_uid = <dtml-sqlvar section_uid type="int"> AND stock.section_uid = <dtml-sqlvar section_uid type="int">
AND movement.variation_text = <dtml-sqlvar variation_text type="string">
\ No newline at end of file
...@@ -60,15 +60,16 @@ if resource <> None : ...@@ -60,15 +60,16 @@ if resource <> None :
corresp_variation_list = [movement.getTaille()]+['value'] corresp_variation_list = [movement.getTaille()]+['value']
# find taille_client # find taille_client
line_taille_client = ' ' line_taille_client = movement.Amount_getTailleClient()
correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
if len(correspondance_list) == 1 : # correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
my_correspondance = correspondance_list[0] # if len(correspondance_list) == 1 :
mapped_value_list = my_correspondance.objectValues() # my_correspondance = correspondance_list[0]
for mapped_value in mapped_value_list : # mapped_value_list = my_correspondance.objectValues()
if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) : # for mapped_value in mapped_value_list :
line_taille_client = mapped_value.getProperty(key='taille_client') # if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) :
break # line_taille_client = mapped_value.getProperty(key='taille_client')
# break
try : try :
line_quantity = float(movement.getProperty(key='quantity')) line_quantity = float(movement.getProperty(key='quantity'))
...@@ -78,21 +79,22 @@ if resource <> None : ...@@ -78,21 +79,22 @@ if resource <> None :
line_date = order_line.aq_parent.getStopDate() line_date = order_line.aq_parent.getStopDate()
# find code_article # find code_article
line_code_article = '' line_code_article = movement.Amount_getCodeArticleClient()
variated_reference_list = resource.contentValues(filter={'portal_type':'Variated Reference'})
# we search a variated_reference wich define 'code_article' # variated_reference_list = resource.contentValues(filter={'portal_type':'Variated Reference'})
my_variated_reference = None # # we search a variated_reference wich define 'code_article'
for variated_reference in variated_reference_list : # my_variated_reference = None
if len(variated_reference.getMappedValuePropertyList()) <> 0 : # for variated_reference in variated_reference_list :
if variated_reference.getMappedValuePropertyList()[0] == 'code_article' : # if len(variated_reference.getMappedValuePropertyList()) <> 0 :
my_variated_reference = variated_reference # if variated_reference.getMappedValuePropertyList()[0] == 'code_article' :
break # my_variated_reference = variated_reference
if my_variated_reference is not None : # break
mapped_value_list = my_variated_reference.objectValues() # if my_variated_reference is not None :
for mapped_value in mapped_value_list : # mapped_value_list = my_variated_reference.objectValues()
if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) : # for mapped_value in mapped_value_list :
line_code_article = mapped_value.getProperty(key='code_article') # if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) :
break # line_code_article = mapped_value.getProperty(key='code_article')
# break
line_items = [line_resource,line_coloris,line_morphologie,line_taille, line_items = [line_resource,line_coloris,line_morphologie,line_taille,
line_taille_client,line_quantity,line_date,line_code_article] line_taille_client,line_quantity,line_date,line_code_article]
......
...@@ -18,7 +18,7 @@ try: ...@@ -18,7 +18,7 @@ try:
if product_reference_list <> '' : if product_reference_list <> '' :
product_list += product_reference_list product_list += product_reference_list
if len(supplier_list) > 0 : elif len(supplier_list) > 0 :
product_raw_list = context.Resource_sqlResourceSupplierSearch(supplier_title_list=supplier_list) product_raw_list = context.Resource_sqlResourceSupplierSearch(supplier_title_list=supplier_list)
for product_item in product_raw_list : for product_item in product_raw_list :
product_list.append(product_item.title) product_list.append(product_item.title)
......
...@@ -28,6 +28,10 @@ try : ...@@ -28,6 +28,10 @@ try :
if line.find(text_list[0]) <> (-1) : # quantity if line.find(text_list[0]) <> (-1) : # quantity
# create previous item # create previous item
# first check if needed if quantity compatible with parent_item
if my_quantity is not None and my_container.getPortalType() == 'Piece Tissu' :
if my_quantity >= my_container.getRemainingQuantity() :
my_quantity = None
if my_quantity is not None : if my_quantity is not None :
compteur += 1 compteur += 1
new_id = str(my_container.generateNewId(default = 40000)) new_id = str(my_container.generateNewId(default = 40000))
......
...@@ -58,7 +58,9 @@ try : ...@@ -58,7 +58,9 @@ try :
except : except :
quantity = 0 quantity = 0
if not quantity in (0, 0.0, '0') : if quantity < 0 :
error_item_list.append(id_and_weight_list[i*2]+'(quantit trop importante)')
elif not quantity in (0, 0.0, '0') :
# create the new item # create the new item
new_id = str(item.generateNewId(default = 40000)) new_id = str(item.generateNewId(default = 40000))
item.portal_types.constructContent(type_name = 'Piece Tissu', item.portal_types.constructContent(type_name = 'Piece Tissu',
...@@ -81,11 +83,11 @@ try : ...@@ -81,11 +83,11 @@ try :
movement_list[0].setItemIdList(new_aggregated_item_id_list) movement_list[0].setItemIdList(new_aggregated_item_id_list)
compteur += 1 compteur += 1
else : else :
error_item_list.append(id_and_weight_list[i*2]+'(conversion)') error_item_list.append(id_and_weight_list[i*2]+'(conversion kg mtre impossible)')
else : else :
error_item_list.append(id_and_weight_list[i*2]+'(non sortie ou plusieurs sorties)') error_item_list.append(id_and_weight_list[i*2]+'(non sortie ou plusieurs sorties)')
else : else :
error_item_list.append(id_and_weight_list[i*2]+'(quantit)') error_item_list.append(id_and_weight_list[i*2]+'(quantit mal dfinie)')
else : else :
error_item_list.append(id_and_weight_list[i*2]+'(inconnue)') error_item_list.append(id_and_weight_list[i*2]+'(inconnue)')
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
<values> <values>
<alternate_name></alternate_name> <alternate_name></alternate_name>
<css_class></css_class> <css_class></css_class>
<default>Delivery_zSearchResource</default> <default>PieceTissu_zGetAvailableItemList</default>
<description></description> <description></description>
<display_maxwidth></display_maxwidth> <display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width> <display_width type="int">20</display_width>
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
<hidden type="int">1</hidden> <hidden type="int">1</hidden>
<max_length></max_length> <max_length></max_length>
<required type="int">0</required> <required type="int">0</required>
<title></title> <title>x</title>
<truncate type="int">0</truncate> <truncate type="int">0</truncate>
</values> </values>
<tales> <tales>
......
# Erase existing auto_planned ## Script (Python) "PortalSimulation_activateRequirementList"
order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()]) ##bind container=container
order_id_list = map(lambda x:x.id,order_list) ##bind context=context
object_id_list = context.ordre_fabrication.objectIds() ##bind namespace=
order_id_list = filter(lambda x: x in object_id_list, order_id_list) ##bind script=script
context.ordre_fabrication.deleteContent(order_id_list) ##bind subpath=traverse_subpath
##parameters=
##title=
##
if 1:
# Erase existing auto_planned
order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
order_id_list = map(lambda x:x.id,order_list)
object_id_list = context.ordre_fabrication.objectIds()
order_id_list = filter(lambda x: x in object_id_list, order_id_list)
context.ordre_fabrication.deleteContent(order_id_list)
order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()]) order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()])
order_id_list = map(lambda x:x.id,order_list) order_id_list = map(lambda x:x.id,order_list)
object_id_list = context.commande_achat.objectIds() object_id_list = context.commande_achat.objectIds()
order_id_list = filter(lambda x: x in object_id_list, order_id_list) order_id_list = filter(lambda x: x in object_id_list, order_id_list)
context.commande_achat.deleteContent(order_id_list) context.commande_achat.deleteContent(order_id_list)
#return "Done"
# Stock sourcing states # Stock sourcing states
#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced') source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'started', 'stopped', 'delivered', 'invoiced')
source_state_list = None #source_state_list = None
# Get inventory list # Get inventory list
inventory_list = context.SimulationTool_getGroupFutureInventoryList(simulation_state=source_state_list) inventory_list = context.SimulationTool_getGroupFutureInventoryList(simulation_state=source_state_list)
...@@ -28,9 +40,9 @@ for inventory_item in inventory_list: ...@@ -28,9 +40,9 @@ for inventory_item in inventory_list:
if movement is not None: if movement is not None:
resource = movement.getResourceValue() resource = movement.getResourceValue()
if resource is not None: if resource is not None:
# Only source negative stock if resource.getPortalType() != "Assortiment":
print "Activate Build Order for %s for missing quantity %s" % (inventory_item.resource_relative_url, inventory_item.inventory) # Only source negative stock
resource.activate(priority=2).PortalSimulation_buildRequirementOrder(resource=inventory_item.resource_relative_url) print "Activate Build Order for %s for missing quantity %s" % (inventory_item.resource_relative_url, inventory_item.inventory)
resource.activate(priority=2).PortalSimulation_buildRequirementOrder(resource=inventory_item.resource_relative_url)
return printed return printed
...@@ -7,21 +7,20 @@ ...@@ -7,21 +7,20 @@
##parameters=resource=None ##parameters=resource=None
##title= ##title=
## ##
from Products.ERP5.Document import newTempMovement
from Products.ERP5Type.Document import newTempMovement
from DateTime import DateTime from DateTime import DateTime
# Stock sourcing states # Stock sourcing states
#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced') source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
source_state_list = None #source_state_list = None
# Default date # Default date
now_date = DateTime() now_date = DateTime(DateTime().Date())
# Get inventory list # Get inventory list
inventory_list = context.SimulationTool_getGroupFutureInventoryList(resource=resource, simulation_state=source_state_list) inventory_list = context.SimulationTool_getGroupFutureInventoryList(resource=resource, simulation_state=source_state_list)
# Commit SQL # Commit SQL
# context.portal_simulation.commitTransaction() context.portal_simulation.commitTransaction()
# First, find out which resources are missing # First, find out which resources are missing
# and build a dictionnary of quantity, variation # and build a dictionnary of quantity, variation
...@@ -40,7 +39,7 @@ for inventory_item in inventory_list: ...@@ -40,7 +39,7 @@ for inventory_item in inventory_list:
#LOG('ZeroStockRule WARNING',0,'None movement found') #LOG('ZeroStockRule WARNING',0,'None movement found')
# Commit SQL # Commit SQL
# context.portal_simulation.commitTransaction() context.portal_simulation.commitTransaction()
# A list of resources to create # A list of resources to create
to_create = quantity_dict.keys() to_create = quantity_dict.keys()
...@@ -93,4 +92,4 @@ for order in order_list: ...@@ -93,4 +92,4 @@ for order in order_list:
order.autoPlan() order.autoPlan()
order.purchase_order_apply_condition() order.purchase_order_apply_condition()
return printed return printed
\ No newline at end of file
...@@ -7,24 +7,12 @@ ...@@ -7,24 +7,12 @@
##parameters= ##parameters=
##title= ##title=
## ##
mlist = context.Resource_zGetMovementHistoryList(resource = ["modele/417P401"],
variation_text = """coloris/modele/417P401/1_espace_stuc
taille/enfant/10 ans""",
section_category = "group/Coramy",
node_category= "site/Stock_PF",
strict_membership = 0,
simulation_state = ('delivered', 'started', 'stopped', 'invoiced'))
print map(lambda x:x.relative_url, mlist)
print "next"
result = context.portal_simulation.updateAssetPrice( result = context.portal_simulation.updateAssetPrice(
"modele/417P401", "modele/417P401",
"""coloris/modele/417P401/1_espace_stuc """coloris/modele/417P401/1_espace_stuc
taille/enfant/10 ans""", taille/enfant/10 ans""",
"group/Coramy", "group/Coramy",
"site/Stock_PF" "site/Stock_PF"
) )
for i in result: for i in result:
......
...@@ -23,9 +23,11 @@ omit_simulation ...@@ -23,9 +23,11 @@ omit_simulation
omit_input omit_input
omit_output omit_output
simulation_state simulation_state
query</params> query
calculate_asset:int=0</params>
SELECT SELECT
SUM(stock.quantity) AS inventory, SUM(stock.quantity) AS inventory,
<dtml-if "calculate_asset != 0"> SUM(stock.total_asset_price) AS asset_price, </dtml-if>
node.title AS node_title, node.title AS node_title,
node.relative_url AS node_relative_url, node.relative_url AS node_relative_url,
section.title AS section_title, section.title AS section_title,
......
...@@ -7,7 +7,9 @@ cache_time:0 ...@@ -7,7 +7,9 @@ cache_time:0
class_name:ZSQLBrain class_name:ZSQLBrain
class_file:zsqlbrain.py class_file:zsqlbrain.py
</dtml-comment> </dtml-comment>
<params>to_date</params> <params>to_date
resource
simulation_state:list</params>
SELECT SELECT
SUM(stock.quantity) as inventory, SUM(stock.quantity) as inventory,
section.title AS section_title, section.title AS section_title,
...@@ -29,7 +31,9 @@ AND stock.section_uid = section_category.uid ...@@ -29,7 +31,9 @@ AND stock.section_uid = section_category.uid
AND (node_category.category_uid=<dtml-var "portal_categories.site.Stock_MP.getUid()"> AND (node_category.category_uid=<dtml-var "portal_categories.site.Stock_MP.getUid()">
OR node_category.category_uid=<dtml-var "portal_categories.site.Stock_PF.getUid()">) OR node_category.category_uid=<dtml-var "portal_categories.site.Stock_PF.getUid()">)
AND stock.node_uid = node_category.uid AND stock.node_uid = node_category.uid
<dtml-if to_date>AND movement.stop_date < <dtml-sqlvar to_date type="string"> <dtml-if resource>AND resource.relative_url = <dtml-sqlvar resource type="string">
</dtml-if><dtml-if to_date> AND movement.stop_date < <dtml-sqlvar to_date type="string">
</dtml-if><dtml-if simulation_state> AND (<dtml-in simulation_state> catalog.simulation_state = <dtml-sqlvar sequence-item type="string"><dtml-if sequence-end><dtml-else> OR </dtml-if></dtml-in>)
</dtml-if> </dtml-if>
GROUP BY GROUP BY
resource.uid, movement.variation_text resource.uid, movement.variation_text
......
...@@ -7,28 +7,35 @@ ...@@ -7,28 +7,35 @@
##parameters= ##parameters=
##title= ##title=
## ##
if 1: return context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
if 0:
# Delete all proposed orders # Delete all proposed orders
for o in context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()]) : #production_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
realo = o.getObject() #context.ordre_fabrication.deleteContent(map(lambda b:b.id, production_list))
realo.aq_parent.deleteContent(realo.getId()) buy_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()])
#return map(lambda b:b.id, buy_list)
#context.commande_achat.deleteContent(map(lambda b:b.id, buy_list))
# Empty Zero Stock # Empty Zero Stock
context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds()) context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
context.portal_simulation.commitTransaction() # Release any SQL locks
# Expand Zero Stock as many times as needed (1 or 2 for the Coramy case) # Expand Zero Stock as many times as needed (1 or 2 for the Coramy case)
# for i in range(0,1): # for i in range(0,1):
context.portal_simulation.zero_stock.expand() context.portal_simulation.portal_simulation.zero_stock.expand()
# Collect movements in Zero Stock applied rule # Collect movements in Zero Stock applied rule
zs_movement_list = context.portal_simulation.zero_stock.contentValues() zs_movement_list = context.portal_simulation.zero_stock.contentValues()
#return len(zs_movement_list )
#context.portal_simulation.commitTransaction() # Release any SQL locks
# keep only movements with a Modele resource # keep only movements with a Modele resource
movement_list = [] movement_list = []
for movement in zs_movement_list[0:100] : for movement in zs_movement_list:
resource_value = movement.getResourceValue() resource_value = movement.getResourceValue()
if resource_value is not None: if resource_value is not None:
#if resource_value.getPortalType() == 'Modele' :
movement_list.append(movement) movement_list.append(movement)
# Parse movements into a root group # Parse movements into a root group
...@@ -40,6 +47,9 @@ for order in order_list: ...@@ -40,6 +47,9 @@ for order in order_list:
order.autoPlan() order.autoPlan()
order.purchase_order_apply_condition() order.purchase_order_apply_condition()
context.portal_simulation.commitTransaction() # Release any SQL locks
return "Done"
# reEmpty Zero Stock because we don't want to see the zero_stock quantities in the columns future_stock # reEmpty Zero Stock because we don't want to see the zero_stock quantities in the columns future_stock
context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds()) context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
<field><id>listbox</id> <type>ListBox</type> <field><id>listbox</id> <type>ListBox</type>
<values> <values>
<all_columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLocation', 'Emplacement')]</all_columns> <all_columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLastLocationTitle', 'Localisation'), ('getLocation', 'Emplacement')]</all_columns>
<all_editable_columns type="list">[]</all_editable_columns> <all_editable_columns type="list">[]</all_editable_columns>
<alternate_name></alternate_name> <alternate_name></alternate_name>
<columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLocation', 'Emplacement')]</columns> <columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLastLocationTitle', 'Localisation'), ('getLocation', 'Emplacement')]</columns>
<css_class></css_class> <css_class></css_class>
<default></default> <default></default>
<default_params type="list">[('id', "''")]</default_params> <default_params type="list">[('id', "''")]</default_params>
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<hidden type="int">0</hidden> <hidden type="int">0</hidden>
<lines type="int">30</lines> <lines type="int">30</lines>
<list_action>list</list_action> <list_action>list</list_action>
<list_method type="method">PieceTissu_zGetAvailableItemList</list_method> <list_method type="method">portal_catalog</list_method>
<meta_types type="list">[]</meta_types> <meta_types type="list">[]</meta_types>
<portal_types type="list">[('Piece Tissu', 'Piece Tissu')]</portal_types> <portal_types type="list">[('Piece Tissu', 'Piece Tissu')]</portal_types>
<report_root_list type="list">[]</report_root_list> <report_root_list type="list">[]</report_root_list>
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
<title>Pices de tissu</title> <title>Pices de tissu</title>
</values> </values>
<tales> <tales>
<list_method>python:here.getPortalObject().portal_skins.local_list_method[here.REQUEST.list_method_id]</list_method>
</tales> </tales>
<messages> <messages>
<message name="external_validator_failed">The input failed the external validator.</message> <message name="external_validator_failed">The input failed the external validator.</message>
......
...@@ -114,6 +114,30 @@ ...@@ -114,6 +114,30 @@
<message name="not_float">You did not enter a floating point number.</message> <message name="not_float">You did not enter a floating point number.</message>
</messages> </messages>
</field> </field>
<field><id>my_last_location_title</id> <type>StringField</type>
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default></default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
<external_validator></external_validator>
<extra></extra>
<hidden type="int">0</hidden>
<max_length></max_length>
<required type="int">0</required>
<title>Localisation</title>
<truncate type="int">0</truncate>
</values>
<tales>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
<message name="required_not_found">Input is required but no input given.</message>
<message name="too_long">Too much input was given.</message>
</messages>
</field>
<field><id>my_location</id> <type>StringField</type> <field><id>my_location</id> <type>StringField</type>
<values> <values>
<alternate_name></alternate_name> <alternate_name></alternate_name>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
##bind namespace= ##bind namespace=
##bind script=script ##bind script=script
##bind subpath=traverse_subpath ##bind subpath=traverse_subpath
##parameters=transformation=None, quantities=1 ##parameters=
##title= ##title=
## ##
transformed_component = context transformed_component = context
...@@ -14,9 +14,8 @@ variation_base_category_list = [] ...@@ -14,9 +14,8 @@ variation_base_category_list = []
q_variation_base_category_list = transformed_component.getQVariationBaseCategoryList() q_variation_base_category_list = transformed_component.getQVariationBaseCategoryList()
v_variation_base_category_list = transformed_component.getVVariationBaseCategoryList() v_variation_base_category_list = transformed_component.getVVariationBaseCategoryList()
if quantities : for base_category in q_variation_base_category_list :
for base_category in q_variation_base_category_list : variation_base_category_list.append(base_category)
variation_base_category_list.append(base_category)
for base_category in v_variation_base_category_list : for base_category in v_variation_base_category_list :
if not base_category in variation_base_category_list : if not base_category in variation_base_category_list :
...@@ -26,7 +25,7 @@ variation_base_category_list.sort() ...@@ -26,7 +25,7 @@ variation_base_category_list.sort()
variation_list_list = [] variation_list_list = []
for base_category in variation_base_category_list : for base_category in variation_base_category_list :
variation_list = transformation.getVariationCategoryList(base_category_list = base_category) variation_list = context.aq_parent.getVariationCategoryList(base_category_list = base_category)
variation_list_list.append(variation_list) variation_list_list.append(variation_list)
cartesian_variation_list = context.cartesianProduct(variation_list_list) cartesian_variation_list = context.cartesianProduct(variation_list_list)
...@@ -55,14 +54,6 @@ for variation_list in cartesian_variation_list : ...@@ -55,14 +54,6 @@ for variation_list in cartesian_variation_list :
pretty_variation_2 = '- ' pretty_variation_2 = '- '
for my_variation in variation : for my_variation in variation :
pretty_variation_2 += my_variation+' - ' pretty_variation_2 += my_variation+' - '
if pretty_variation_2 == '- ' : correspondance_list.append([pretty_variation_1, quantity, pretty_variation_2])
try :
pretty_variation_2 += transformed_component.getVariationCategoryList()[0]
except :
pass
if quantities :
correspondance_list.append([pretty_variation_1, quantity, pretty_variation_2])
else :
correspondance_list.append([pretty_variation_1, '', pretty_variation_2])
return correspondance_list return correspondance_list
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
<tr> <tr>
<td colspan="3" > <td colspan="3" >
<table class="border" border="0" width="100%" <table class="border" border="0" width="100%"
tal:define="correspondances_list python:transformed_resource.TransformedComponent_getCorrespondanceList(transformation,quantities=0)"> tal:define="correspondances_list python:transformed_resource.TransformedComponent_getCorrespondanceList()">
<tr tal:condition="python:len(correspondances_list)==0"> <tr tal:condition="python:len(correspondances_list)==0">
<td> <td>
<span tal:repeat="variation_item python:transformed_resource.getVariationCategoryList()"> <span tal:repeat="variation_item python:transformed_resource.getVariationCategoryList()">
......
...@@ -47,6 +47,8 @@ elif local_user == 'Jocelyne_Olejarz' : ...@@ -47,6 +47,8 @@ elif local_user == 'Jocelyne_Olejarz' :
printer_name = 'Meto_XS40_4' printer_name = 'Meto_XS40_4'
elif local_user == 'Nathalie_Wadoux' : elif local_user == 'Nathalie_Wadoux' :
printer_name = 'Meto_XS40_5' printer_name = 'Meto_XS40_5'
elif local_user == 'Chantal_Hannequin' :
printer_name = 'Meto_XS40_6'
else : else :
printer_name = 'Meto_XS40_2' printer_name = 'Meto_XS40_2'
......
...@@ -22,6 +22,8 @@ elif local_user == 'Jocelyne_Olejarz' : ...@@ -22,6 +22,8 @@ elif local_user == 'Jocelyne_Olejarz' :
printer_name = 'Meto_XS40_4' printer_name = 'Meto_XS40_4'
elif local_user == 'Nathalie_Wadoux' : elif local_user == 'Nathalie_Wadoux' :
printer_name = 'Meto_XS40_5' printer_name = 'Meto_XS40_5'
elif local_user == 'Chantal_Hannequin' :
printer_name = 'Meto_XS40_6'
else : else :
printer_name = 'Meto_XS40_2' printer_name = 'Meto_XS40_2'
......
...@@ -21,7 +21,7 @@ def decoupe(s,width): ...@@ -21,7 +21,7 @@ def decoupe(s,width):
result = s[-width:] result = s[-width:]
else: else:
#result = string.ljust(s,width) #result = string.ljust(s,width)
result = (' ' * (width-len(s))) + s result = s + (' ' * (width-len(s)))
#return ' '+s #return ' '+s
return result return result
......
...@@ -20,8 +20,8 @@ def category_property(category, property): ...@@ -20,8 +20,8 @@ def category_property(category, property):
else : else :
return " " return " "
for taille in taille_list : if len(taille_list) == 0 :
my_taille = 'taille/'+taille my_taille = None
if coloris is not None and morphologie is not None : if coloris is not None and morphologie is not None :
my_coloris = 'coloris/'+coloris my_coloris = 'coloris/'+coloris
my_morphologie = 'morphologie/'+morphologie my_morphologie = 'morphologie/'+morphologie
...@@ -40,5 +40,26 @@ for taille in taille_list : ...@@ -40,5 +40,26 @@ for taille in taille_list :
target_quantity_list.append(delivery_line.getCell(None, my_taille, base_id='movement').getProperty(key="target_quantity")) target_quantity_list.append(delivery_line.getCell(None, my_taille, base_id='movement').getProperty(key="target_quantity"))
else : else :
target_quantity_list.append(0) target_quantity_list.append(0)
else :
for taille in taille_list :
my_taille = 'taille/'+taille
if coloris is not None and morphologie is not None :
my_coloris = 'coloris/'+coloris
my_morphologie = 'morphologie/'+morphologie
if delivery_line.getCell(my_coloris, my_taille, my_morphologie, base_id='movement') <> None :
target_quantity_list.append(delivery_line.getCell(my_coloris, my_taille, my_morphologie, base_id='movement').getProperty(key="target_quantity"))
else :
target_quantity_list.append(0)
elif coloris is not None :
my_coloris = 'coloris/'+coloris
if delivery_line.getCell(my_coloris, my_taille, base_id='movement') <> None :
target_quantity_list.append(delivery_line.getCell(my_coloris, my_taille, base_id='movement').getProperty(key="target_quantity"))
else :
target_quantity_list.append(0)
else : # coloris is None :
if delivery_line.getCell(None, my_taille, base_id='movement') <> None :
target_quantity_list.append(delivery_line.getCell(None, my_taille, base_id='movement').getProperty(key="target_quantity"))
else :
target_quantity_list.append(0)
return target_quantity_list return target_quantity_list
...@@ -31,7 +31,10 @@ for container_item in container_list : ...@@ -31,7 +31,10 @@ for container_item in container_list :
ligne_container += str(container.getGrossWeight())+tab ligne_container += str(container.getGrossWeight())+tab
ligne_container += first_line.getResourceValue().getId()+tab ligne_container += first_line.getResourceValue().getId()+tab
ligne_container += delivery.getDestinationSectionTitle()+tab ligne_container += delivery.getDestinationSectionTitle()+tab
ligne_container += first_line.getColorisValue().getId()+tab if first_line.getColorisValue() is not None :
ligne_container += first_line.getColorisValue().getId()+tab
else :
ligne_container += ''+tab
ligne_container += first_line.Amount_getTailleClient()+tab ligne_container += first_line.Amount_getTailleClient()+tab
ligne_container += "Maillot de bain"+tab ligne_container += "Maillot de bain"+tab
ligne_container += first_line.Amount_getCodeArticleClient()+tab ligne_container += first_line.Amount_getCodeArticleClient()+tab
......
...@@ -10,16 +10,34 @@ ...@@ -10,16 +10,34 @@
allowsplitting="1" allowsplitting="1"
tal:define="packing_list python:here.getCausalityValueList(portal_type=['Sale Packing List','Sales Packing List'])[0]; tal:define="packing_list python:here.getCausalityValueList(portal_type=['Sale Packing List','Sales Packing List'])[0];
invoice_id python:here.getId(); invoice_id python:here.getId();
invoice_reference python: here.getReference(0);
resource_title python:here.getResourceTitle() or 'Euros'; resource_title python:here.getResourceTitle() or 'Euros';
resource_id python:here.getResourceId() or 'EUR'; resource_id python:here.getResourceId() or 'EUR';
income python: here.income; income python: here.Invoice_zGetTotalNetPrice();
vat python: here.vat; vat python: here.Invoice_zGetTotalVat();
payable python: here.payable;"> payable python: here.getDefaultTotalPrice();
payable python: income + vat;
vad_recoverable python: here.getValueAddedTaxRecoverable();
vad_ratio python: here.getValueAddedTaxRatio();
source_decision_title python: here.getSourceDecisionTitle();
payment_mode python: here.getPaymentMode();
payment_term python: here.getPaymentTerm(30);
incoterm python: packing_list.getIncotermId();
delivery_mode python: packing_list.getDeliveryModeTitle().split('/')[-1];
escompte_value python: here.Invoice_zGetEscompteDescription();
container_number python: len(packing_list.contentValues(filter={'portal_type':'Container'}));
total_price python:here.getDefaultTotalPrice();">
<!-- due_date python: DateTime.getNextMonth(start_date.month(), start_date.year()) ; -->
<tal:block <tal:block
tal:define="destination python: packing_list.getDestinationValue(); tal:define="destination python: here.getDestinationValue();
destination_administration python: packing_list.getDestinationAdministrationValue() or packing_list.getDestinationSectionValue(); destination_administration python: here.getDestinationAdministrationValue() or here.getDestinationSectionValue();
start_date python:packing_list.getStartDate(); DateTime python: modules['DateTime'].DateTime;
start_date python:here.getStartDate( packing_list.getTargetStopDate() ) ;
due_date python: here.Invoice_zGetDueDate();
packing_list_id python:packing_list.getId(); packing_list_id python:packing_list.getId();
code_comptable python: destination_administration.getCodeComptable();
eu_vat_code python: destination_administration.getEuVatCode();
order python:packing_list.getCausalityValueList(portal_type=['Sale Order','Sales Order'])[0];"> order python:packing_list.getCausalityValueList(portal_type=['Sale Order','Sales Order'])[0];">
<stylesheet> <stylesheet>
...@@ -78,7 +96,8 @@ ...@@ -78,7 +96,8 @@
<stylecmd expr="('RIGHTPADDING', (0,0), (-1,-1), 5)"/> <stylecmd expr="('RIGHTPADDING', (0,0), (-1,-1), 5)"/>
<stylecmd expr="('TOPPADDING', (0,0), (-1,-1), 1)"/> <stylecmd expr="('TOPPADDING', (0,0), (-1,-1), 1)"/>
<stylecmd expr="('BOTTOMPADDING', (0,0), (-1,-1), 1)"/> <stylecmd expr="('BOTTOMPADDING', (0,0), (-1,-1), 1)"/>
<stylecmd expr="('ALIGN', (0,0), (-1,-1), 'LEFT')"/> <stylecmd expr="('ALIGN', (0,0), (1,0), 'LEFT')"/>
<stylecmd expr="('ALIGN', (2,0), (-1,-1), 'RIGHT')"/>
<stylecmd expr="('GRID', (0,0), (-1,-1), 0, colors.white)"/> <stylecmd expr="('GRID', (0,0), (-1,-1), 0, colors.white)"/>
<stylecmd expr="('BOX', (0,0), (-1,-1), 0, colors.white)"/> <stylecmd expr="('BOX', (0,0), (-1,-1), 0, colors.white)"/>
<stylecmd expr="('FONT', (0,0), (-1,-1), 'Helvetica', 8)"/> <stylecmd expr="('FONT', (0,0), (-1,-1), 'Helvetica', 8)"/>
...@@ -132,7 +151,7 @@ ...@@ -132,7 +151,7 @@
</stylesheet> </stylesheet>
<pagetemplate id="FirstPage" nextid="Page" startframe="content"> <pagetemplate id="FirstPage" nextid="SecondPage" startframe="content">
<static> <static>
<!-- Entete CORAMY --> <!-- Entete CORAMY -->
...@@ -159,21 +178,21 @@ ...@@ -159,21 +178,21 @@
<!-- Titre du document (Facture n) --> <!-- Titre du document (Facture n) -->
<infostring align="left" x="6.8cm" y="26cm" size="16" <infostring align="left" x="6.8cm" y="26cm" size="16"
font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n %s' % invoice_id"> font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n %s' % invoice_reference">
Facture n 105 915 Facture n XXX
</infostring> </infostring>
<infostring align="left" x="14cm" y="26cm" size="8" <infostring align="left" x="14cm" y="26cm" size="8"
font="Helvetica" color="(0,0,0)" tal:content="python: start_date.strftime('Gravelines, le %e/%m/%y')"> font="Helvetica" color="(0,0,0)" tal:content="python: start_date.strftime('Gravelines, le %e/%m/%y')">
Gravelines, le 9/07/03 Gravelines, le XXX
</infostring> </infostring>
<infostring align="left" x="18.5cm" y="26cm" size="8" <infostring align="left" x="18.5cm" y="26cm" size="8"
font="Helvetica-Bold" color="(0,0,0)"> font="Helvetica-Bold" color="(0,0,0)">
Folio 1 Folio %(page)s
</infostring> </infostring>
<!-- Grand cadre de la fature --> <!-- Grand cadre de la facture -->
<line x1="1cm" x2="20.5cm" y1="25cm" y2="25cm" width="1"/> <line x1="1cm" x2="20.5cm" y1="25cm" y2="25cm" width="1"/>
<line x1="1cm" x2="1cm" y1="25cm" y2="4cm" width="1"/> <line x1="1cm" x2="1cm" y1="25cm" y2="4cm" width="1"/>
<line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/> <line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/>
...@@ -195,7 +214,7 @@ ...@@ -195,7 +214,7 @@
</infostring> </infostring>
<infostring align="center" x="2.5cm" y="24.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)" <infostring align="center" x="2.5cm" y="24.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: order.getDestinationReference()"> tal:content="python: order.getDestinationReference()">
7286007 DestinationReference XXX
</infostring> </infostring>
<infostring align="left" x="1.7cm" y="23.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="1.7cm" y="23.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
...@@ -206,7 +225,7 @@ ...@@ -206,7 +225,7 @@
</infostring> </infostring>
<infostring align="center" x="2.5cm" y="23.3cm" size="8" font="Helvetica-Bold" color="(0,0,0)" <infostring align="center" x="2.5cm" y="23.3cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: order.getId()"> tal:content="python: order.getId()">
119 022 Order.id XXX
</infostring> </infostring>
<infostring align="left" x="1.1cm" y="22.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="1.1cm" y="22.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
...@@ -217,33 +236,23 @@ ...@@ -217,33 +236,23 @@
</infostring> </infostring>
<infostring align="center" x="2.5cm" y="22.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)" <infostring align="center" x="2.5cm" y="22.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: packing_list_id"> tal:content="python: packing_list_id">
108 301 PackingListId XXX
</infostring> </infostring>
<infostring align="left" x="1.1cm" y="21.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="1.7cm" y="21.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Nombre de colis Nombre de colis
</infostring> </infostring>
<infostring align="left" x="1.3cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="1.9cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Kolli anzahl Kolli anzahl
</infostring> </infostring>
<infostring align="left" x="1.2cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="1.8cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Nb of parcels Nb of parcels
</infostring> </infostring>
<infostring align="left" x="3.5cm" y="21.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="center" x="2.5cm" y="21.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
32 tal:content="python: container_number">
</infostring> NbrColis XXX
<infostring align="left" x="1.1cm" y="21cm" size="6" font="Helvetica" color="(0,0,0)">
Poids brut (kg)
</infostring>
<infostring align="left" x="1.2cm" y="20.8cm" size="6" font="Helvetica" color="(0,0,0)">
Brutto-gewicht
</infostring>
<infostring align="left" x="1.3cm" y="20.6cm" size="6" font="Helvetica" color="(0,0,0)">
Gross weight
</infostring> </infostring>
<infostring align="left" x="6cm" y="24.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="6cm" y="24.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Livraison / Versand / Delivery Livraison / Versand / Delivery
</infostring> </infostring>
...@@ -279,36 +288,30 @@ ...@@ -279,36 +288,30 @@
</tal:block> </tal:block>
<infostring align="left" x="4.5cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="4.5cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Commercial Commercial
</infostring> </infostring>
<infostring align="left" x="4.4cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="6cm" y="21.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: source_decision_title ">
Commercial XXX
</infostring>
<infostring align="left" x="4.4cm" y="21.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Paiement Paiement
</infostring> </infostring>
<infostring align="left" x="4.6cm" y="21.3cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="4.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Zahlung Zahlung
</infostring> </infostring>
<infostring align="left" x="4.5cm" y="21.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="4.5cm" y="20.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Payment Payment
</infostring> </infostring>
<infostring align="left" x="4.3cm" y="20.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="5.8cm" y="21cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
Device / Currency / Wahrung tal:content="python: payment_mode ">
</infostring> payment_modeXXX
<infostring align="left" x="5.8cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
Cheque
</infostring>
<infostring align="left" x="5.8cm" y="21.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
20 jours Net
</infostring> </infostring>
<infostring align="left" x="8.5cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)" <infostring align="left" x="5.8cm" y="20.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: resource_title"> tal:content="python: '%i jours Net' % payment_term">
Euros payment_termXXX
</infostring> </infostring>
<infostring align="left" x="10.2cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: resource_id">
EUR
</infostring>
<infostring align="left" x="11.6cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="11.6cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Code comptable Code comptable
...@@ -319,47 +322,50 @@ ...@@ -319,47 +322,50 @@
<infostring align="left" x="11.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="11.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Conditions d'escompte / Diskont / Discount. Conditions d'escompte / Diskont / Discount.
</infostring> </infostring>
<infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
41REDOU tal:content="python: code_comptable">
CodeComptable XXX
</infostring> </infostring>
<infostring align="left" x="11.6cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="left" x="14cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
2,75 sous 20 jours tal:content="python: eu_vat_code">
NoTVAXXX
</infostring>
<infostring align="left" x="11.6cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: escompte_value">
Escompte XXX
</infostring> </infostring>
<infostring align="left" x="18.9cm" y="24.6cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Port / Porto <infostring align="left" x="18.9cm" y="24.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
</infostring>
<infostring align="left" x="19.1cm" y="24.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Freight
</infostring>
<infostring align="left" x="19cm" y="24cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
Franco
</infostring>
<infostring align="left" x="18.9cm" y="23.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Transporteur Transporteur
</infostring> </infostring>
<infostring align="left" x="18.6cm" y="23.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="18.6cm" y="24cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Carrier / Spediteur Carrier / Spediteur
</infostring> </infostring>
<infostring align="left" x="18.8cm" y="22.8cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="center" x="19.5cm" y="23.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
CORAMY tal:content="python: delivery_mode">
delivery_modeXXX
</infostring> </infostring>
<infostring align="left" x="18.6cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="18.6cm" y="23cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Transport Transport
</infostring> </infostring>
<infostring align="left" x="20cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="left" x="20cm" y="23cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
3 3
</infostring> </infostring>
<infostring align="left" x="18.6cm" y="21.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="18.6cm" y="22.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Transaction Transaction
</infostring> </infostring>
<infostring align="left" x="19.9cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="left" x="19.9cm" y="22.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
11 11
</infostring> </infostring>
<infostring align="left" x="18.6cm" y="20.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)"> <infostring align="left" x="18.6cm" y="21.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Livraison Livraison
</infostring> </infostring>
<infostring align="left" x="19.9cm" y="21.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: incoterm">
incotermXXX
</infostring>
<!-- Dtail de la facture --> <!-- Dtail de la facture -->
<rectangle x="1cm" y="19.9cm" width="19.5cm" height="0.4cm" <rectangle x="1cm" y="19.9cm" width="19.5cm" height="0.4cm"
...@@ -368,15 +374,15 @@ ...@@ -368,15 +374,15 @@
<infostring align="left" x="2.8cm" y="20cm" size="9" <infostring align="left" x="2.8cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
Denomination des produits Dnomination des produits
</infostring> </infostring>
<infostring align="left" x="10cm" y="20cm" size="9" <infostring align="left" x="10cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
Repartition par tailles Rpartition par tailles
</infostring> </infostring>
<infostring align="left" x="15.4cm" y="20cm" size="9" <infostring align="left" x="15.4cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
Quantite Quantit
</infostring> </infostring>
<infostring align="left" x="17.1cm" y="20cm" size="9" <infostring align="left" x="17.1cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
...@@ -409,10 +415,12 @@ ...@@ -409,10 +415,12 @@
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
T.V.A. T.V.A.
</infostring> </infostring>
<infostring align="left" x="9.3cm" y="5.1cm" size="9" <tal:block tal:condition="python: vad_recoverable">
font="Helvetica" color="(0,0,0)"> <infostring align="left" x="9.3cm" y="5.1cm" size="9"
19,6%% font="Helvetica" color="(0,0,0)" tal:content="python: '%.1f' % (vad_ratio * 100) + '%%'">
</infostring> 19,6%%
</infostring>
</tal:block>
<infostring align="left" x="11.2cm" y="5.5cm" size="9" <infostring align="left" x="11.2cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)"> font="Helvetica-Oblique" color="(0,0,0)">
Port Port
...@@ -440,48 +448,249 @@ ...@@ -440,48 +448,249 @@
<infostring align="center" x="2.2cm" y="4.5cm" size="9" <infostring align="center" x="2.2cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)" font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % income.getSourceCredit()"> tal:content="python: '%.2f' % income">
14 408,46 income XXX
</infostring> </infostring>
<infostring align="left" x="6.5cm" y="4.5cm" size="9" <infostring align="center" x="3.8cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"> font="Helvetica" color="(0,0,0)">
14 408,46
</infostring> </infostring>
<infostring align="center" x="9.7cm" y="4.5cm" size="9" <infostring align="left" x="6.5cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)" font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % vat.getSourceCredit()"> tal:content="python: '%.2f' % income">
2 824,06
</infostring>
<tal:block tal:condition="python: vad_recoverable">
<infostring align="center" x="9.7cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % vat">
vat XXX
</infostring>
</tal:block>
<infostring align="left" x="10.7cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)">
</infostring> </infostring>
<infostring align="center" x="13.8cm" y="4.5cm" size="10" <infostring align="center" x="13.8cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: '%.2f' % payable.getSourceDebit()"> tal:content="python: '%.2f' % payable">
17 232,52 payable XXX
</infostring> </infostring>
<infostring align="center" x="16cm" y="4.5cm" size="10" <infostring align="center" x="16cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: resource_id"> tal:content="python: resource_id">
EUR resource_id XXX
</infostring> </infostring>
<infostring align="left" x="18cm" y="4.5cm" size="10" <infostring align="left" x="18cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)"> font="Helvetica-Bold" color="(0,0,0)"
31/07/03 tal:content="python: due_date.strftime('%e/%m/%y')">
due_date XXX
</infostring> </infostring>
<infostring align="left" x="1.1cm" y="3.8cm" size="5" font="Helvetica" color="(0,0,0)"> <infostring align="left" x="1.1cm" y="3.8cm" size="5" font="Helvetica" color="(0,0,0)">
En application de la loi du 31/12/1992, nous vous precisons que la presente facture devra etre reglee a la date indiquee ci-dessous. En cas de reglement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionne purra etre deduit du En application de la loi du 31/12/1992, nous vous prcisons que la presente facture devra tre rgle la date indique ci-dessus. En cas de rglement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionn pourra tre dduit du
</infostring> </infostring>
<infostring align="left" x="1.1cm" y="3.5cm" size="5" font="Helvetica" color="(0,0,0)"> <infostring align="left" x="1.1cm" y="3.5cm" size="5" font="Helvetica" color="(0,0,0)">
montant H.T. de la facture, auquel cas le montant de TVA deductible par vous devra etre diminue du montant de celle affrente a l'escompte. Son rglement donnera lieu au versement d'un intrt moratoire, calcule sur les sommes restant montant H.T. de la facture, auquel cas le montant de TVA dductible par vous devra tre diminu du montant de celle affrente l'escompte. Son rglement donnera lieu au versement d'un intrt moratoire, calcul sur les sommes restant
</infostring> </infostring>
<infostring align="left" x="1.1cm" y="3.2cm" size="5" font="Helvetica" color="(0,0,0)"> <infostring align="left" x="1.1cm" y="3.2cm" size="5" font="Helvetica" color="(0,0,0)">
dues a cette date de reglement en principal, frais et taxes inclus, et au taux de l'interet legal majore de 5 points, sans que cette penalite puisse etre en toute hypothese inferieure a 1,5 fois le taux de l'interet legal. dues cette date de rglement en principal, frais et taxes inclus, et au taux de l'intrt lgal major de 5 points, sans que cette pnalit puisse tre en toute hypothse infrieure 1,5 fois le taux de l'intrt lgal.
</infostring>
</static>
<frame id="content"
nextid="content"
x="1cm"
y="5.8cm"
width="19.5cm"
height="14.1cm"
leftpadding="0.1cm"
rightpadding="0.1cm"
toppadding="0.2cm"
bottompadding="0.5cm"
showBoundary="1"/>
</pagetemplate>
<pagetemplate id="SecondPage" nextid="SecondPage" startframe="content">
<static>
<!-- Entete CORAMY -->
<infostring align="left" x="1.4cm" y="28cm" size="40"
font="Times-Bold" color="(0,0,0)">Coramy</infostring>
<rectangle x="1cm" y="28cm" width="0.3cm" height="0.4cm"
linewidth="0.0" stroke="(1,1,1)" fill="(0.5,0.5,0.5)"/>
<rectangle x="6.5cm" y="28cm" width="13.5cm" height="0.4cm"
linewidth="0.0" stroke="(1,1,1)" fill="(0.5,0.5,0.5)"/>
<infostring align="left" x="7cm" y="28.5cm" size="8"
font="Helvetica" color="(0,0,0)">
5 bis, rue Denis Cordonnier - F.59820 GRAVELINES - Tel. 33(0)3 28 51 91 51 - Fax 33(0)3 28 23 34 96
</infostring>
<infostring align="left" x="10cm" y="28.1cm" size="8"
font="Helvetica" color="(1,1,1)">
MAILLOTS DE BAIN - GYM - SWIMSUITS - FITNESS
</infostring>
<infostring align="left" x="6.8cm" y="27.7cm" size="6"
font="Helvetica" color="(0,0,0)">
SAS capital de 435.200 EUR - T.V.A. FR 67 611 750 274 - R.C. Dunkerque 611 750 274 - SIRET 611 750 274 00023 - CNUF 15971
</infostring>
<!-- Titre du document (Facture n) -->
<infostring align="left" x="6.8cm" y="26cm" size="16"
font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n %s' % invoice_reference">
Facture n XXX
</infostring>
<infostring align="left" x="14cm" y="26cm" size="8"
font="Helvetica" color="(0,0,0)" tal:content="python: start_date.strftime('Gravelines, le %e/%m/%y')">
Gravelines, le XXX
</infostring>
<infostring align="left" x="18.5cm" y="26cm" size="8"
font="Helvetica-Bold" color="(0,0,0)">
Folio %(page)s
</infostring>
<!-- Grand cadre de la facture -->
<line x1="1cm" x2="20.5cm" y1="25cm" y2="25cm" width="1"/>
<line x1="1cm" x2="1cm" y1="25cm" y2="4cm" width="1"/>
<line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/>
<line x1="1cm" x2="20.5cm" y1="4cm" y2="4cm" width="1"/>
<!-- Dtail de la facture -->
<rectangle x="1cm" y="24.6cm" width="19.5cm" height="0.4cm"
linewidth="0" fill="(0.75,0.75,0.75)"/>
<line x1="1cm" x2="20.5cm" y1="24.6cm" y2="24.6cm" width="1"/>
<infostring align="left" x="2.8cm" y="24.7cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Dnomination des produits
</infostring>
<infostring align="left" x="10cm" y="24.7cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Rpartition par tailles
</infostring>
<infostring align="left" x="15.4cm" y="24.7cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Quantit
</infostring>
<infostring align="left" x="17.1cm" y="24.7cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
P.U.H.T.
</infostring>
<infostring align="left" x="18.8cm" y="24.7cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Total H.T.
</infostring>
<!-- Pied de facture -->
<rectangle x="1cm" y="5.0cm" width="19.5cm" height="0.8cm"
linewidth="0" fill="(0.75,0.75,0.75)"/>
<line x1="1cm" x2="20.5cm" y1="5.8cm" y2="5.8cm" width="1"/>
<line x1="1cm" x2="20.5cm" y1="5.0cm" y2="5.0cm" width="1"/>
<infostring align="left" x="1.5cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Total H.T.
</infostring>
<infostring align="left" x="3.8cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Port taxable
</infostring>
<infostring align="left" x="6.2cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Montant taxable
</infostring>
<infostring align="left" x="9.2cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
T.V.A.
</infostring>
<tal:block tal:condition="python: vad_recoverable">
<infostring align="left" x="9.3cm" y="5.1cm" size="9"
font="Helvetica" color="(0,0,0)" tal:content="python: '%.1f' % (vad_ratio * 100) + '%%'">
19,6%%
</infostring>
</tal:block>
<infostring align="left" x="11.2cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Port
</infostring>
<infostring align="left" x="10.7cm" y="5.1cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
non taxable
</infostring>
<infostring align="left" x="13.8cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Net a payer
</infostring>
<infostring align="left" x="12.6cm" y="5.1cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Gesamtbetrag / Total amount
</infostring>
<infostring align="left" x="17.5cm" y="5.5cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Date d'echeance
</infostring>
<infostring align="left" x="17cm" y="5.1cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Falligkeitstag / Due date
</infostring> </infostring>
<infostring align="left" x="1.6cm" y="2.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="center" x="2.2cm" y="4.5cm" size="9"
Nos marchandises sont grevees d'une clause de reserve de propriete, reprise dans nos conditions generales de venteindiquees au verso font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % income">
income XXX
</infostring> </infostring>
<infostring align="left" x="4.5cm" y="2.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"> <infostring align="center" x="3.8cm" y="4.5cm" size="9"
Allegemeine Verkaufsbedingungen auf ruckseite - General sales conditions overleaf font="Helvetica" color="(0,0,0)">
</infostring>
<infostring align="left" x="6.5cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % income">
</infostring>
<tal:block tal:condition="python: vad_recoverable">
<infostring align="center" x="9.7cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % vat">
vat XXX
</infostring>
</tal:block>
<infostring align="left" x="10.7cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)">
</infostring>
<infostring align="center" x="13.8cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: '%.2f' % payable">
payable XXX
</infostring>
<infostring align="center" x="16cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: resource_id">
resource_id XXX
</infostring>
<infostring align="left" x="18cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: due_date.strftime('%e/%m/%y')">
due_date XXX
</infostring>
<infostring align="left" x="1.1cm" y="3.8cm" size="5" font="Helvetica" color="(0,0,0)">
En application de la loi du 31/12/1992, nous vous prcisons que la presente facture devra tre rgle la date indique ci-dessus. En cas de rglement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionn pourra tre dduit du
</infostring>
<infostring align="left" x="1.1cm" y="3.5cm" size="5" font="Helvetica" color="(0,0,0)">
montant H.T. de la facture, auquel cas le montant de TVA dductible par vous devra tre diminu du montant de celle affrente l'escompte. Son rglement donnera lieu au versement d'un intrt moratoire, calcul sur les sommes restant
</infostring>
<infostring align="left" x="1.1cm" y="3.2cm" size="5" font="Helvetica" color="(0,0,0)">
dues cette date de rglement en principal, frais et taxes inclus, et au taux de l'intrt lgal major de 5 points, sans que cette pnalit puisse tre en toute hypothse infrieure 1,5 fois le taux de l'intrt lgal.
</infostring> </infostring>
</static> </static>
...@@ -491,7 +700,7 @@ ...@@ -491,7 +700,7 @@
x="1cm" x="1cm"
y="5.8cm" y="5.8cm"
width="19.5cm" width="19.5cm"
height="14.1cm" height="18.8cm"
leftpadding="0.1cm" leftpadding="0.1cm"
rightpadding="0.1cm" rightpadding="0.1cm"
toppadding="0.2cm" toppadding="0.2cm"
...@@ -499,6 +708,10 @@ ...@@ -499,6 +708,10 @@
showBoundary="1"/> showBoundary="1"/>
</pagetemplate> </pagetemplate>
<pagetemplate id="Page" > <pagetemplate id="Page" >
<static> <static>
...@@ -522,4 +735,4 @@ ...@@ -522,4 +735,4 @@
</pagetemplate> </pagetemplate>
</tal:block> </tal:block>
</template> </template>
\ No newline at end of file
...@@ -500,10 +500,10 @@ ...@@ -500,10 +500,10 @@
<field><id>listbox</id> <type>ListBox</type> <field><id>listbox</id> <type>ListBox</type>
<values> <values>
<all_columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('quantity_unit', 'Unit\xe9')]</all_columns> <all_columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('price', 'Prix'), ('quantity_unit', 'Unit\xe9')]</all_columns>
<all_editable_columns type="list">[]</all_editable_columns> <all_editable_columns type="list">[]</all_editable_columns>
<alternate_name></alternate_name> <alternate_name></alternate_name>
<columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('getPurchaseDeliveryCellSourceReference', 'R\xe9f. fournisseur'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('quantity_unit', 'Unit\xe9')]</columns> <columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('getPurchaseDeliveryCellSourceReference', 'R\xe9f. fournisseur'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('price', 'Prix'), ('quantity_unit', 'Unit\xe9')]</columns>
<css_class></css_class> <css_class></css_class>
<default></default> <default></default>
<default_params type="list">[]</default_params> <default_params type="list">[]</default_params>
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
<field><id>listbox</id> <type>ListBox</type> <field><id>listbox</id> <type>ListBox</type>
<values> <values>
<all_columns type="list">[('id', 'Commande'), ('default_destination_title', 'Client'), ('buyer_title', 'Acheteur'), ('Description', 'Description'), ('order_state', 'Etat')]</all_columns> <all_columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</all_columns>
<all_editable_columns type="list">[]</all_editable_columns> <all_editable_columns type="list">[]</all_editable_columns>
<alternate_name></alternate_name> <alternate_name></alternate_name>
<columns type="list">[('id', 'Facture'), ('default_destination_title', 'Client'), ('buyer_title', 'Acheteur'), ('Description', 'Description'), ('order_state', 'Etat')]</columns> <columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</columns>
<css_class></css_class> <css_class></css_class>
<default></default> <default></default>
<default_params type="list">[('id', "''")]</default_params> <default_params type="list">[('id', "''")]</default_params>
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<report_root_list type="list">[]</report_root_list> <report_root_list type="list">[]</report_root_list>
<report_tree type="int">0</report_tree> <report_tree type="int">0</report_tree>
<search type="int">1</search> <search type="int">1</search>
<search_columns type="list">[]</search_columns> <search_columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</search_columns>
<select type="int">1</select> <select type="int">1</select>
<selection_name>order_selection</selection_name> <selection_name>order_selection</selection_name>
<sort type="list">[('id', 'id')]</sort> <sort type="list">[('id', 'id')]</sort>
......
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
<TD align="left" tal:content="python:'coloris '+coloris_list[1][index]"></TD> <TD align="left" tal:content="python:'coloris '+coloris_list[1][index]"></TD>
<SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/> <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/>
<SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2],coloris_list[2][index])"> <SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2],coloris_list[2][index])">
<TD align = right tal:content="python: '%.0f' %target_quantity"/> <TD tal:condition="python:taille_qty!=0" align = "right" tal:content="python: '%.0f' %target_quantity"/>
<SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/> <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/>
</SPAN> </SPAN>
<TD align="right" tal:content="python: '%.0f' %totalizer[2]"/> <TD align="right" tal:content="python: '%.0f' %totalizer[2]"/>
...@@ -112,7 +112,8 @@ ...@@ -112,7 +112,8 @@
<TR><!-- PAS DE COLORIS --> <TR><!-- PAS DE COLORIS -->
<TD align="left"></TD> <TD align="left"></TD>
<SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/> <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/>
<SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2])"> <SPAN tal:condition="python:taille_qty!=0"
tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2])">
<TD align = right tal:content="python: '%.0f' %target_quantity"/> <TD align = right tal:content="python: '%.0f' %target_quantity"/>
<SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/> <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/>
</SPAN> </SPAN>
......
...@@ -116,17 +116,18 @@ class Amount(Base, Variated): ...@@ -116,17 +116,18 @@ class Amount(Base, Variated):
self._setVariationValue(variation_value) self._setVariationValue(variation_value)
self.reindexObject() self.reindexObject()
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getVariationRangeCategoryItemList') 'getVariationRangeCategoryItemList')
def getVariationRangeCategoryItemList(self, base_category_list = (), def getVariationRangeCategoryItemList(self, base_category_list = (),
method_id='getTitle', base=1, current_category=None): method_id='getTitle', base=1, start_with_item=None):
""" """
Returns possible category items for this amount ie. Returns possible category items for this amount ie.
the variation of the resource (not the variation range) the variation of the resource (not the variation range)
""" """
try: try:
return self.getDefaultResourceValue().getVariationCategoryItemList( return self.getDefaultResourceValue().getVariationCategoryItemList(
base_category_list, method_id=method_id, base=base, current_category=current_category) base_category_list, method_id=method_id, base=base, start_with_item=start_with_item)
except: except:
# FIXME: method_name vs. method_id, start_with_item vs. start_with_empty, etc. -yo # FIXME: method_name vs. method_id, start_with_item vs. start_with_empty, etc. -yo
return self.portal_categories.getCategoryChildItemList() return self.portal_categories.getCategoryChildItemList()
...@@ -294,7 +295,7 @@ class Amount(Base, Variated): ...@@ -294,7 +295,7 @@ class Amount(Base, Variated):
""" """
quantity = self.getConvertedTargetQuantity() quantity = self.getConvertedTargetQuantity()
efficiency = self.getTargetEfficiency() efficiency = self.getTargetEfficiency()
if efficiency in (0, 0.0, None): if efficiency in (0, 0.0, None, ''):
efficiency = 1.0 efficiency = 1.0
if quantity not in (None, ''): if quantity not in (None, ''):
return float(quantity) / efficiency return float(quantity) / efficiency
...@@ -425,6 +426,15 @@ class Amount(Base, Variated): ...@@ -425,6 +426,15 @@ class Amount(Base, Variated):
else: else:
return 0.0 return 0.0
# Inventory
security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
def getConvertedInventory(self):
"""
provides a default inventory value - None since
no inventory was defined.
"""
return None
# Profit and Loss # Profit and Loss
security.declareProtected(Permissions.ModifyPortalContent, 'getLostQuantity') security.declareProtected(Permissions.ModifyPortalContent, 'getLostQuantity')
def getLostQuantity(self): def getLostQuantity(self):
......
...@@ -204,3 +204,17 @@ Une ligne tarifaire.""" ...@@ -204,3 +204,17 @@ Une ligne tarifaire."""
more_result += container.getContainerText() more_result += container.getContainerText()
result = result + '\n'.join(map(lambda x: " %s" % x, more_result.split('\n'))) result = result + '\n'.join(map(lambda x: " %s" % x, more_result.split('\n')))
return result return result
# Used for optimization - requires reindexing using container_uid
security.declareProtected(Permissions.AccessContentsInformation, 'getContainerUid')
def getContainerUid(self):
return self.getUid()
security.declareProtected(Permissions.AccessContentsInformation, 'getContainerValue')
def getContainerValue(self):
return self
security.declareProtected(Permissions.AccessContentsInformation, 'getContainer')
def getContainer(self):
return self.getRelativeUrl()
...@@ -257,6 +257,7 @@ Une ligne tarifaire.""" ...@@ -257,6 +257,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell in the quantity attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -270,7 +271,17 @@ Une ligne tarifaire.""" ...@@ -270,7 +271,17 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# now verify if item can be moved (not already done)
last_location_title = object.getLastLocationTitle()
if self.getDestinationTitle() != last_location_title or last_location_title == '' :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -284,6 +295,8 @@ Une ligne tarifaire.""" ...@@ -284,6 +295,8 @@ Une ligne tarifaire."""
quantity += object_item.getQuantity() quantity += object_item.getQuantity()
else : else :
quantity += object_item.getRemainingQuantity() quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setTargetQuantity(quantity) self.setTargetQuantity(quantity)
...@@ -305,6 +318,30 @@ Une ligne tarifaire.""" ...@@ -305,6 +318,30 @@ Une ligne tarifaire."""
else: else:
return Movement.getInventoriatedQuantity(self) return Movement.getInventoriatedQuantity(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
def getStartDate(self):
"""
Take into account efficiency in converted target quantity
"""
if self.getSimulationState() in current_inventory_state_list:
# When an order is delivered, the target quantity should be considered
# rather than the quantity
return Movement.getTargetStartDate(self)
else:
return Movement.getStartDate(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
def getStopDate(self):
"""
Take into account efficiency in converted target quantity
"""
if self.getSimulationState() in current_inventory_state_list:
# When an order is delivered, the target quantity should be considered
# rather than the quantity
return Movement.getTargetStopDate(self)
else:
return Movement.getStopDate(self)
# Simulation Consistency Check # Simulation Consistency Check
def getRelatedQuantity(self): def getRelatedQuantity(self):
""" """
......
...@@ -30,6 +30,8 @@ from Globals import InitializeClass, PersistentMapping ...@@ -30,6 +30,8 @@ from Globals import InitializeClass, PersistentMapping
from Acquisition import aq_base, aq_inner, aq_parent, aq_self from Acquisition import aq_base, aq_inner, aq_parent, aq_self
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5.ERP5Globals import current_inventory_state_list
from Products.CMFCore.WorkflowCore import WorkflowAction from Products.CMFCore.WorkflowCore import WorkflowAction
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
...@@ -137,9 +139,9 @@ Une ligne tarifaire.""" ...@@ -137,9 +139,9 @@ Une ligne tarifaire."""
# Update consumption last # Update consumption last
if item_id_list is not None: if item_id_list is not None:
self._setItemIdList(item_id_list) self._setItemIdList(item_id_list)
elif produced_item_id_list is not None: if produced_item_id_list is not None :
self._setProducedItemIdList(produced_item_id_list) self._setProducedItemIdList(produced_item_id_list)
elif consumed_item_id_list is not None: if consumed_item_id_list is not None :
self._setConsumedItemIdList(consumed_item_id_list) self._setConsumedItemIdList(consumed_item_id_list)
security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' ) security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' )
...@@ -180,6 +182,9 @@ Une ligne tarifaire.""" ...@@ -180,6 +182,9 @@ Une ligne tarifaire."""
quantity = self._baseGetQuantity() quantity = self._baseGetQuantity()
if quantity not in (0.0, 0, None): if quantity not in (0.0, 0, None):
return quantity return quantity
# Make sure inventory is defined somewhere (here or parent)
if getattr(aq_base(self), 'inventory', None) is None:
return 0.0 # No inventory defined, so no quantity
# Find total of movements in the past - XXX # Find total of movements in the past - XXX
resource_value = self.getResourceValue() resource_value = self.getResourceValue()
if resource_value is not None: if resource_value is not None:
...@@ -189,10 +194,11 @@ Une ligne tarifaire.""" ...@@ -189,10 +194,11 @@ Une ligne tarifaire."""
at_date = self.getStartDate(), at_date = self.getStartDate(),
variation_text = self.getVariationText(), variation_text = self.getVariationText(),
node = self.getDestination(), node = self.getDestination(),
section = self.getDestinationSection()) section = self.getDestinationSection(),
simulation_state = current_inventory_state_list)
inventory = self.getInventory() inventory = self.getInventory()
if inventory in (None, ''): if current_inventory in (None, ''):
return None # Do not change inventory if no inventory value provided current_inventory = 0.0
return self.getInventory() - current_inventory return self.getInventory() - current_inventory
return self.getInventory() return self.getInventory()
...@@ -216,6 +222,7 @@ Une ligne tarifaire.""" ...@@ -216,6 +222,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the inventory attribute of the cell in the inventory attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -229,7 +236,14 @@ Une ligne tarifaire.""" ...@@ -229,7 +236,14 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -240,7 +254,7 @@ Une ligne tarifaire.""" ...@@ -240,7 +254,7 @@ Une ligne tarifaire."""
quantity = 0 quantity = 0
for object_item in item_object_list : for object_item in item_object_list :
quantity += object_item.getQuantity() quantity += object_item.getRemainingQuantity()
self.setInventory(quantity) self.setInventory(quantity)
...@@ -252,11 +266,27 @@ Une ligne tarifaire.""" ...@@ -252,11 +266,27 @@ Une ligne tarifaire."""
""" """
return Movement.getInventoriatedQuantity(self) return Movement.getInventoriatedQuantity(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
def getStartDate(self):
"""
Take into account efficiency in converted target quantity
"""
return Movement.getStartDate(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
def getStopDate(self):
"""
Take into account efficiency in converted target quantity
"""
return Movement.getStopDate(self)
def _setProducedItemIdList(self, value): def _setProducedItemIdList(self, value):
""" """
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell in the quantity attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -270,7 +300,17 @@ Une ligne tarifaire.""" ...@@ -270,7 +300,17 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# now verify if item can be moved (not already done)
last_location_title = object.getLastLocationTitle()
if self.getDestinationTitle() != last_location_title or last_location_title == '' :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -290,6 +330,7 @@ Une ligne tarifaire.""" ...@@ -290,6 +330,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell in the quantity attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -303,7 +344,17 @@ Une ligne tarifaire.""" ...@@ -303,7 +344,17 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# now verify if item can be moved (not already done)
last_location_title = object.getLastLocationTitle()
if self.getDestinationTitle() == last_location_title or last_location_title == '' :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -315,6 +366,8 @@ Une ligne tarifaire.""" ...@@ -315,6 +366,8 @@ Une ligne tarifaire."""
for object_item in item_object_list : for object_item in item_object_list :
quantity += object_item.getRemainingQuantity() quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setConsumptionQuantity(quantity) self.setConsumptionQuantity(quantity)
...@@ -335,3 +388,12 @@ Une ligne tarifaire.""" ...@@ -335,3 +388,12 @@ Une ligne tarifaire."""
return self.getItemIdList() return self.getItemIdList()
else : else :
return [] return []
# Inventory cataloging
security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
def getConvertedInventory(self):
"""
provides a default inventory value - None since
no inventory was defined.
"""
return self.getInventory() # XXX quantity unit is missing
...@@ -130,6 +130,23 @@ Une ligne tarifaire.""" ...@@ -130,6 +130,23 @@ Une ligne tarifaire."""
) )
} }
def _edit(self, REQUEST=None, force_update = 0, **kw):
kw = kw.copy()
item_id_list = kw.get('item_id_list', None)
if item_id_list is not None: del kw['item_id_list']
produced_item_id_list = kw.get('produced_item_id_list', None)
if produced_item_id_list is not None: del kw['produced_item_id_list']
consumed_item_id_list = kw.get('consumed_item_id_list', None)
if consumed_item_id_list is not None: del kw['consumed_item_id_list']
DeliveryLine._edit(self, REQUEST=REQUEST, force_update = force_update, **kw)
# Update consumption last
if item_id_list is not None:
self._setItemIdList(item_id_list)
if produced_item_id_list is not None :
self._setProducedItemIdList(produced_item_id_list)
if consumed_item_id_list is not None :
self._setConsumedItemIdList(consumed_item_id_list)
security.declareProtected(Permissions.AccessContentsInformation, 'getTotalInventory') security.declareProtected(Permissions.AccessContentsInformation, 'getTotalInventory')
def getTotalInventory(self): def getTotalInventory(self):
""" """
...@@ -153,7 +170,9 @@ Une ligne tarifaire.""" ...@@ -153,7 +170,9 @@ Une ligne tarifaire."""
quantity = self._baseGetQuantity() quantity = self._baseGetQuantity()
if quantity not in (0.0, 0, None): if quantity not in (0.0, 0, None):
return quantity return quantity
return self.getInventory() # Make sure inventory is defined somewhere (here or parent)
if getattr(aq_base(self), 'inventory', None) is None:
return 0.0 # No inventory defined, so no quantity
# Find total of movements in the past - XXX # Find total of movements in the past - XXX
resource_value = self.getResourceValue() resource_value = self.getResourceValue()
if resource_value is not None: if resource_value is not None:
...@@ -166,8 +185,8 @@ Une ligne tarifaire.""" ...@@ -166,8 +185,8 @@ Une ligne tarifaire."""
section = self.getDestinationSection(), section = self.getDestinationSection(),
simulation_state = current_inventory_state_list) simulation_state = current_inventory_state_list)
inventory = self.getInventory() inventory = self.getInventory()
if inventory in (None, ''): if current_inventory in (None, ''):
return None # Do not change inventory if no inventory value provided current_inventory = 0.0
return self.getInventory() - current_inventory return self.getInventory() - current_inventory
return self.getInventory() return self.getInventory()
else: else:
...@@ -229,6 +248,7 @@ Une ligne tarifaire.""" ...@@ -229,6 +248,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the inventory attribute of the cell in the inventory attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -242,7 +262,14 @@ Une ligne tarifaire.""" ...@@ -242,7 +262,14 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -262,6 +289,7 @@ Une ligne tarifaire.""" ...@@ -262,6 +289,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell in the quantity attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -275,7 +303,17 @@ Une ligne tarifaire.""" ...@@ -275,7 +303,17 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# now verify if item can be moved (not already done)
last_location_title = object.getLastLocationTitle()
if self.getDestinationTitle() != last_location_title or last_location_title == '' :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -295,6 +333,7 @@ Une ligne tarifaire.""" ...@@ -295,6 +333,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell in the quantity attribute of the cell
""" """
previous_item_list = self.getAggregateValueList()
given_item_id_list = value given_item_id_list = value
item_object_list = [] item_object_list = []
for item in given_item_id_list : for item in given_item_id_list :
...@@ -308,7 +347,17 @@ Une ligne tarifaire.""" ...@@ -308,7 +347,17 @@ Une ligne tarifaire."""
object = None object = None
if object is not None : if object is not None :
item_object_list.append(object) # if item was in previous_item_list keep it
if object in previous_item_list :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# if new item verify if variated_resource of item == variated_resource of movement
elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
# now verify if item can be moved (not already done)
last_location_title = object.getLastLocationTitle()
if self.getDestinationTitle() == last_location_title or last_location_title == '' :
# we can add this item to the list of aggregated items
item_object_list.append(object)
# update item_id_list and build relation # update item_id_list and build relation
self.setAggregateValueList(item_object_list) self.setAggregateValueList(item_object_list)
...@@ -320,6 +369,8 @@ Une ligne tarifaire.""" ...@@ -320,6 +369,8 @@ Une ligne tarifaire."""
for object_item in item_object_list : for object_item in item_object_list :
quantity += object_item.getRemainingQuantity() quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setConsumptionQuantity(quantity) self.setConsumptionQuantity(quantity)
...@@ -340,3 +391,35 @@ Une ligne tarifaire.""" ...@@ -340,3 +391,35 @@ Une ligne tarifaire."""
return self.getItemIdList() return self.getItemIdList()
else : else :
return [] return []
# Inventory cataloging
security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
def getConvertedInventory(self):
"""
provides a default inventory value - None since
no inventory was defined.
"""
return self.getInventory() # XXX quantity unit is missing
# Required for indexing
security.declareProtected(Permissions.AccessContentsInformation, 'getInventoriatedQuantity')
def getInventoriatedQuantity(self):
"""
Take into account efficiency in converted target quantity
"""
return Movement.getInventoriatedQuantity(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
def getStartDate(self):
"""
Take into account efficiency in converted target quantity
"""
return Movement.getStartDate(self)
security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
def getStopDate(self):
"""
Take into account efficiency in converted target quantity
"""
return Movement.getStopDate(self)
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.CMFCore.utils import getToolByName
from AccountingTransaction import AccountingTransaction from AccountingTransaction import AccountingTransaction
class Invoice(AccountingTransaction): class Invoice(AccountingTransaction):
...@@ -55,6 +55,9 @@ class Invoice(AccountingTransaction): ...@@ -55,6 +55,9 @@ class Invoice(AccountingTransaction):
, PropertySheet.Amount , PropertySheet.Amount
, PropertySheet.Reference , PropertySheet.Reference
, PropertySheet.PaymentCondition , PropertySheet.PaymentCondition
, PropertySheet.ValueAddedTax
, PropertySheet.EcoTax
, PropertySheet.CopyrightTax
) )
# CMF Factory Type Information # CMF Factory Type Information
...@@ -111,3 +114,34 @@ An order...""" ...@@ -111,3 +114,34 @@ An order..."""
) )
} }
security.declareProtected(Permissions.AccessContentsInformation, 'getTotalPrice')
def getTotalPrice(self):
"""
Returns the total price for this invoice
"""
aggregate = self.Invoice_zGetTotal()[0]
return aggregate.total_price
security.declareProtected(Permissions.AccessContentsInformation, 'getTotalQuantity')
def getTotalQuantity(self):
"""
Returns the total quantity for this invoice
"""
aggregate = self.Invoice_zGetTotal()[0]
return aggregate.total_quantity
security.declareProtected(Permissions.AccessContentsInformation, 'getTotalNetPrice')
def getTotalNetPrice(self):
"""
Returns the total net price for this invoice
"""
return self.Invoice_zGetTotalNetPrice()
security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationSate')
def getSimulationState(self, id_only=1):
"""
Returns the current state in simulation
"""
portal_workflow = getToolByName(self, 'portal_workflow')
wf = portal_workflow.getWorkflowById('sale_invoice_transaction_workflow')
return wf._getWorkflowStateOf(self, id_only=id_only )
...@@ -315,55 +315,49 @@ a service in a public administration).""" ...@@ -315,55 +315,49 @@ a service in a public administration)."""
""" """
return self.getTargetQuantity() return self.getTargetQuantity()
# Industrial price API
security.declareProtected(Permissions.AccessContentsInformation, 'getIndustrialPrice')
def getIndustrialPrice(self):
"""
Calculates industrial price in context of this movement
"""
resource = self.getResourceValue()
if resource is not None:
return resource.getIndustrialPrice(context=self)
return None
# Asset price calculation # Asset price calculation
security.declareProtected(Permissions.AccessContentsInformation, 'getAssetPrice') security.declareProtected(Permissions.AccessContentsInformation, 'getSourceTotalAssetPrice')
def getAssetPrice(self, exclude_path_list = []): def getSourceTotalAssetPrice(self):
""" """
Returns a price which can be used to calculate stock value (asset) Returns a price which can be used to calculate stock value (asset)
""" """
source_value = self.getSourceValue() try:
if not source_value: price = self.getSourceAssetPrice()
# This is a production movement if price is None:
return self.getIndustrialPrice() return None
if not source_value.isMemberOf('group/Coramy'): quantity = self.getQuantity()
# accountable price if quantity is None:
return self.getPrice() return None
# This is an internal movement return quantity * price
current_asset_price = 0.0 except:
current_inventory = 0.0 return None
exclude_path_list.append(self.getRelativeUrl()) # Prevent infinite loops
for m in self.Movement_zGetPastMovementList(node_uid = self.getSourceUid(), section_uid = self.getDestinationUid(), security.declareProtected(Permissions.AccessContentsInformation, 'getDestinationTotalAssetPrice')
before_date = self.getStartDate()): def getDestinationTotalAssetPrice(self):
# NB we may want to consider instead all movements at the group level
# movements should be sorted by date
movement = m.getObject()
if movement is not None and m.relative_url not in exclude_path_list:
# Only considere non loop movements
inventory = m.quantity
if inventory >= 0:
# We use asset_price inside Coramy Group
asset_price = movement.getAssetPrice(exclude_path_list = exclude_path_list) # ???
# Update price
previous_inventory = current_inventory
current_inventory += inventory
if current_inventory > 0:
# Update price with an average of incoming goods and current goods
current_asset_price = ( current_asset_price * previous_inventory + asset_price * inventory ) / float(current_inventory)
else:
# New price is the price of incoming goods - negative stock has no meaning for asset calculation
current_asset_price = asset_price
else:
# No change in asset_price - accumulate inventory
current_inventory += inventory
return current_asset_price
security.declareProtected(Permissions.AccessContentsInformation, 'getTotalAssetPrice')
def getTotalAssetPrice(self):
""" """
Returns a price which can be used to calculate stock value (asset) Returns a price which can be used to calculate stock value (asset)
""" """
return self.getAssetPrice() * self.getQuantity() try:
price = self.getDestinationAssetPrice()
if price is None:
return None
quantity = self.getQuantity()
if quantity is None:
return None
return quantity * price
except:
return None
# Causality computation # Causality computation
security.declareProtected(Permissions.View, 'isConvergent') security.declareProtected(Permissions.View, 'isConvergent')
......
...@@ -215,11 +215,50 @@ An order...""" ...@@ -215,11 +215,50 @@ An order..."""
""" """
Sets the order to ordered Sets the order to ordered
(a Workflow Script is responsible of creating the delivery) (a Workflow Script is responsible of creating the delivery)
Confirm is still not creating deliveries XXX - check activities seriously to make sure
they are not flushed in case of error
""" """
self._createOrderRule() self._createOrderRule()
# At confirm stage, we create deliveries for this order
self.activate().buildDeliveryList()
confirm = WorkflowMethod(_confirm, 'confirm') confirm = WorkflowMethod(_confirm, 'confirm')
security.declareProtected(Permissions.ModifyPortalContent, 'buildDeliveryList')
def buildDeliveryList(self):
# Make sure there is exactly one applied rule
my_applied_rule_list = self.getCausalityRelatedValueList(portal_type='Applied Rule')
if len(my_applied_rule_list) != 1:
# Make sure we have an order rule
self._createOrderRule()
# Make sure there is exactly one applied rule
my_applied_rule_list = self.getCausalityRelatedValueList(portal_type='Applied Rule')
if len(my_applied_rule_list) != 1:
# XXX This is an error
return
applied_rule = my_applied_rule_list[0].getObject()
if applied_rule is None:
# XXX This is an error
return
# Make sure applied rule has been reindexed
applied_rule.flushActivity(invoke=1)
# Make sure there are no more activities on this order related to expand
self.flushActivity(invoke=1, method_id='expand') # Make sure expand is finished
# Build delivery list on applied rule
# Currently, we build it 'again' but we should actually only build
# deliveries for orphaned movements
if self.getPortalType() == 'Production Order' :
delivery_list = self.ProductionOrder_buildDeliveryList() # Coramy specific moved to portal_simulation
elif self.getPortalType() in ('Purchase Order', 'Sales Order') :
delivery_list = self.order_create_packing_list() # Coramy specific should be moved to portal_simulation
#self.informDeliveryList(delivery_list=delivery_list, comment=repr(delivery_list)) # XXX Not ready
def _informDeliveryList(self, delivery_list=None, comment=None):
pass
informDeliveryList = WorkflowMethod(_informDeliveryList, id='informDeliveryList')
security.declareProtected(Permissions.ModifyPortalContent, 'cancel') security.declareProtected(Permissions.ModifyPortalContent, 'cancel')
def cancel(self): def cancel(self):
""" """
......
...@@ -30,6 +30,7 @@ from Globals import InitializeClass, PersistentMapping ...@@ -30,6 +30,7 @@ from Globals import InitializeClass, PersistentMapping
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5.ERP5Globals import movement_type_list, draft_order_state from Products.ERP5.ERP5Globals import movement_type_list, draft_order_state
from Products.CMFCore.utils import getToolByName
from Delivery import Delivery from Delivery import Delivery
......
...@@ -406,7 +406,9 @@ a service in a public administration).""" ...@@ -406,7 +406,9 @@ a service in a public administration)."""
section=section, section=section,
node=node, node=node,
node_category=node_category, node_category=node_category,
section_category=section_category, **kw) section_category=section_category,
simulation_state=simulation_state,
**kw)
return result return result
security.declareProtected(Permissions.AccessContentsInformation, 'getMovementHistoryStat') security.declareProtected(Permissions.AccessContentsInformation, 'getMovementHistoryStat')
...@@ -423,6 +425,7 @@ a service in a public administration).""" ...@@ -423,6 +425,7 @@ a service in a public administration)."""
section=section, section=section,
node=node, node=node,
node_category=node_category, node_category=node_category,
simulation_state=simulation_state,
section_category=section_category, **kw) section_category=section_category, **kw)
return result return result
...@@ -494,3 +497,23 @@ a service in a public administration).""" ...@@ -494,3 +497,23 @@ a service in a public administration)."""
return None return None
# Industrial price API
security.declareProtected(Permissions.AccessContentsInformation, 'getIndustrialPrice')
def getIndustrialPrice(self, context=None, REQUEST=None, **kw):
"""
Returns industrial price
"""
context = self.asContext(context=context, REQUEST=REQUEST, **kw)
result = self._getIndustrialPrice(context)
if result is None:
self._updateIndustrialPrice()
result = self._getIndustrialPrice(context)
return result
def _getIndustrialPrice(self, context):
# Default value is None
return None
def _updateIndustrialPrice(self, context):
# Do nothing by default
pass
...@@ -288,7 +288,7 @@ une gamme...""" ...@@ -288,7 +288,7 @@ une gamme..."""
for transformation in transformation_list: for transformation in transformation_list:
# Browse each transformed or assorted resource of the current transformation # Browse each transformed or assorted resource of the current transformation
for transformed_resource in transformation.objectValues(): for transformed_resource in transformation.objectValues():
LOG("for transformed_resource in transformation",0,transformed_resource.getId()) #LOG("for transformed_resource in transformation",0,transformed_resource.getId())
line_item_list, total_base_price, total_source_base_price, \ line_item_list, total_base_price, total_source_base_price, \
total_variated_base_price, total_variated_source_base_price, duration \ total_variated_base_price, total_variated_source_base_price, duration \
= transformed_resource.getAggregatedAmountList(REQUEST) = transformed_resource.getAggregatedAmountList(REQUEST)
......
...@@ -186,7 +186,7 @@ An ERP5 Rule...""" ...@@ -186,7 +186,7 @@ An ERP5 Rule..."""
source = source_section = 'role/Fournisseur' source = source_section = 'role/Fournisseur'
destination_section = 'group/Coramy' destination_section = 'group/Coramy'
destination = 'site/Stock_MP/Gravelines' destination = 'site/Stock_MP/Gravelines'
movement.edit(target_quantity = movement.getTargetQuantity() + quantity_dict[key]) movement._edit(target_quantity = movement.getTargetQuantity() + quantity_dict[key])
movement._edit( target_start_date = stop_date, movement._edit( target_start_date = stop_date,
target_stop_date = stop_date, target_stop_date = stop_date,
source = source, source = source,
......
...@@ -37,7 +37,7 @@ variation_type_list = ('Variation', 'Variante Tissu', 'Variante Modele', ...@@ -37,7 +37,7 @@ variation_type_list = ('Variation', 'Variante Tissu', 'Variante Modele',
node_type_list = ('Organisation','Person','Category','MetaNode',) node_type_list = ('Organisation','Person','Category','MetaNode',)
invoice_type_list = ('Invoice', 'Sale Invoice', 'Sales Invoice') invoice_type_list = ('Invoice', 'Sale Invoice', 'Sales Invoice', 'Sale Invoice Transaction')
order_type_list = ('Order', 'Project', 'Samples Order', order_type_list = ('Order', 'Project', 'Samples Order',
'Production Order', 'Purchase Order', 'Sale Order', 'Production Order', 'Purchase Order', 'Sale Order',
...@@ -63,6 +63,7 @@ delivery_type_list = ('Delivery', ...@@ -63,6 +63,7 @@ delivery_type_list = ('Delivery',
order_or_delivery_type_list = tuple(list(order_type_list) + list(delivery_type_list)) order_or_delivery_type_list = tuple(list(order_type_list) + list(delivery_type_list))
variation_base_category_list = ('coloris', 'taille', 'variante', 'morphologie') variation_base_category_list = ('coloris', 'taille', 'variante', 'morphologie')
variation_base_category_id_list = variation_base_category_list # Temp Patch
invoice_movement_type_list = ( invoice_movement_type_list = (
'Invoice Line', 'Invoice Line',
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# #
############################################################################## ##############################################################################
from Products.ERP5.ERP5Globals import default_section_category, current_inventory_state_list, reserved_inventory_state_list from Products.ERP5.ERP5Globals import default_section_category, current_inventory_state_list, reserved_inventory_state_list,future_inventory_state_list
from Products.ZSQLCatalog.zsqlbrain import ZSQLBrain from Products.ZSQLCatalog.zsqlbrain import ZSQLBrain
from DateTime import DateTime from DateTime import DateTime
from ZTUtils import make_query from ZTUtils import make_query
...@@ -52,7 +52,7 @@ class InventoryBrain(ZSQLBrain): ...@@ -52,7 +52,7 @@ class InventoryBrain(ZSQLBrain):
""" """
Returns current inventory Returns current inventory
""" """
return self.getInventory(ignore_variation=1) return self.getInventory(ignore_variation=1,simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
def getAvailableInventory(self): def getAvailableInventory(self):
""" """
...@@ -61,24 +61,15 @@ class InventoryBrain(ZSQLBrain): ...@@ -61,24 +61,15 @@ class InventoryBrain(ZSQLBrain):
at_date=DateTime() at_date=DateTime()
current = self.getCurrentInventory() current = self.getCurrentInventory()
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1, result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1,
from_date=at_date, omit_simulation = 1, omit_input = 1, omit_simulation = 1, omit_input = 1,
section_category = default_section_category, section_category = default_section_category,
simulation_state = None) simulation_state = reserved_inventory_state_list)
reserved_inventory = None reserved_inventory = None
if len(result) > 0: if len(result) > 0:
reserved_inventory = result[0].inventory reserved_inventory = result[0].inventory
if reserved_inventory is None: if reserved_inventory is None:
reserved_inventory = 0.0 reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1, return current + reserved_inventory
to_date=at_date, omit_simulation = 1, omit_input = 1,
section_category = default_section_category,
simulation_state = ('confirmed', 'getting_ready', 'ready'))
past_reserved_inventory = None
if len(result) > 0:
past_reserved_inventory = result[0].inventory
if past_reserved_inventory is None:
past_reserved_inventory = 0.0
return current + reserved_inventory + past_reserved_inventory
def getQuantityUnit(self, **kw): def getQuantityUnit(self, **kw):
try: try:
...@@ -123,7 +114,7 @@ class InventoryListBrain(ZSQLBrain): ...@@ -123,7 +114,7 @@ class InventoryListBrain(ZSQLBrain):
""" """
Returns current inventory Returns current inventory
""" """
return self.getInventory(ignore_variation=0) return self.getInventory(ignore_variation=0, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
def getAvailableInventory(self): def getAvailableInventory(self):
""" """
...@@ -132,28 +123,17 @@ class InventoryListBrain(ZSQLBrain): ...@@ -132,28 +123,17 @@ class InventoryListBrain(ZSQLBrain):
at_date=DateTime() at_date=DateTime()
current = self.getCurrentInventory() current = self.getCurrentInventory()
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
from_date=at_date, omit_simulation = 1, omit_input = 1, omit_simulation = 1, omit_input = 1,
section=self.section_relative_url, section=self.section_relative_url,
node=self.node_relative_url, node=self.node_relative_url,
variation_text = self.variation_text, variation_text = self.variation_text,
simulation_state = None) simulation_state = reserved_inventory_state_list)
reserved_inventory = None reserved_inventory = None
if len(result) > 0: if len(result) > 0:
reserved_inventory = result[0].inventory reserved_inventory = result[0].inventory
if reserved_inventory is None: if reserved_inventory is None:
reserved_inventory = 0.0 reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], return current + reserved_inventory
to_date=at_date, omit_simulation = 1, omit_input = 1,
section=self.section_relative_url,
node=self.node_relative_url,
variation_text = self.variation_text,
simulation_state = ('confirmed', 'getting_ready', 'ready'))
past_reserved_inventory = None
if len(result) > 0:
past_reserved_inventory = result[0].inventory
if past_reserved_inventory is None:
past_reserved_inventory = 0.0
return current + reserved_inventory + past_reserved_inventory
def getQuantity(self, **kw): def getQuantity(self, **kw):
result = self.Delivery_zGetTotal( resource_uid = [self.resource_uid], result = self.Delivery_zGetTotal( resource_uid = [self.resource_uid],
...@@ -201,12 +181,27 @@ class InventoryListBrain(ZSQLBrain): ...@@ -201,12 +181,27 @@ class InventoryListBrain(ZSQLBrain):
) )
elif cname_id in ('getCurrentInventory',): elif cname_id in ('getCurrentInventory',):
resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url) resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
return '%s/Resource_movementHistoryView?%s' % (resource.absolute_url(), return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index, make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index,
simulation_state=list(current_inventory_state_list))) simulation_state=list(current_inventory_state_list)))
elif cname_id in ('getAvailableInventory',):
resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index,omit_simulation = 1, omit_input = 1,
simulation_state=list(reserved_inventory_state_list)))
elif cname_id in ('getFutureInventory','inventory', ):
resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
make_query(variation_text=self.variation_text,
selection_name=selection_name, selection_index=selection_index, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)))
elif cname_id in ('getInventoryAtDate',):
resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
make_query(variation_text=self.variation_text, to_date=self.at_date,
selection_name=selection_name, selection_index=selection_index, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)))
else: else:
resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url) resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
return '%s/Resource_movementHistoryView?%s' % (resource.absolute_url(), return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index)) make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index))
except: except:
return '' return ''
...@@ -231,13 +226,18 @@ class InventoryListBrain(ZSQLBrain): ...@@ -231,13 +226,18 @@ class InventoryListBrain(ZSQLBrain):
if portal_type == "Simulation Movement": if portal_type == "Simulation Movement":
order = o.getExplanationValue() order = o.getExplanationValue()
if order is not None: if order is not None:
return "Simulated Order %s" % (order.getId()) return "%s %s" % ('Simulated Order', order.getId()) # Tried to use unicode but failed - ListBot must use unicode in % replacements
else: else:
LOG("Delivery Value",0,str(self.path)) LOG("Delivery Value",0,str(self.path))
delivery = o.getExplanationValue() delivery = o.getExplanationValue()
LOG("Delivery Value",0,str(delivery)) LOG("Delivery Value",0,str(delivery))
if delivery is not None: if delivery is not None:
return "%s %s" % (delivery.getPortalType(), delivery.getId()) causality = delivery.getCausalityValue()
if causality is None:
return "%s %s" % (delivery.getPortalType(), delivery.getId())
else:
return "%s %s (%s %s)" % (delivery.getPortalType(), delivery.getId(),
causality.getPortalType(), causality.getId())
return "Unknown" return "Unknown"
class DeliveryListBrain(InventoryListBrain): class DeliveryListBrain(InventoryListBrain):
...@@ -274,42 +274,22 @@ class DeliveryListBrain(InventoryListBrain): ...@@ -274,42 +274,22 @@ class DeliveryListBrain(InventoryListBrain):
at_date=DateTime() at_date=DateTime()
current = self.getCurrentInventory() current = self.getCurrentInventory()
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
from_date=at_date, omit_simulation = 1, omit_input = 1, omit_simulation = 1, omit_input = 1,
section_category = default_section_category, section_category = default_section_category,
variation_text = self.variation_text, variation_text = self.variation_text,
simulation_state = None) simulation_state = reserved_inventory_state_list )
reserved_inventory = None reserved_inventory = None
if len(result) > 0: if len(result) > 0:
reserved_inventory = result[0].inventory reserved_inventory = result[0].inventory
if reserved_inventory is None: if reserved_inventory is None:
reserved_inventory = 0.0 reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], return current + reserved_inventory
to_date=at_date, omit_simulation = 1, omit_input = 1,
section_category = default_section_category,
variation_text = self.variation_text,
simulation_state = ('confirmed', 'getting_ready', 'ready'))
past_reserved_inventory = None
if len(result) > 0:
past_reserved_inventory = result[0].inventory
if past_reserved_inventory is None:
past_reserved_inventory = 0.0
return current + reserved_inventory + past_reserved_inventory
def getAvailableInventoryAtDate(self): def getInventoryAtDate(self):
""" """
Returns available inventory at the date provided by the SQL method Returns inventory at the date provided by the SQL method
""" """
at_date=self.at_date at_date=self.at_date
current = self.getCurrentInventory() LOG("At Date",0,str(at_date))
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], return self.getInventory(at_date=at_date, ignore_variation=0, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
from_date=at_date, omit_simulation = 1, omit_input = 1,
section_category = default_section_category,
variation_text = self.variation_text,
simulation_state = None)
reserved_inventory = None
if len(result) > 0:
reserved_inventory = result[0].inventory
if reserved_inventory is None:
reserved_inventory = 0.0
return current + reserved_inventory
from Coordinate import Coordinate
from Entity import Entity from Entity import Entity
from Predicate import Predicate from Predicate import Predicate
from Coordinate import Coordinate
from Variated import Variated from Variated import Variated
\ No newline at end of file
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
from Products.ERP5.Tool.SimulationTool import registerTargetSolver from Products.ERP5.Tool.SimulationTool import registerTargetSolver
from CopyToTarget import CopyToTarget from CopyToTarget import CopyToTarget
from zLOG import LOG
class SplitAndDefer(CopyToTarget): class SplitAndDefer(CopyToTarget):
""" """
......
...@@ -67,15 +67,17 @@ class Variated(Base): ...@@ -67,15 +67,17 @@ class Variated(Base):
""" """
return self._getVariationCategoryList(base_category_list = base_category_list) return self._getVariationCategoryList(base_category_list = base_category_list)
security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList') security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList')
def getVariationCategoryItemList(self, base_category_list = (), base=1, def getVariationCategoryItemList(self, base_category_list = (), base=1,
method_id='getTitle', current_category=None): method_id='getTitle', start_with_item=None):
""" """
Returns the list of possible variation items Returns the list of possible variations
""" """
variation_category_item_list = [] variation_category_item_list = []
if current_category is not None: if start_with_item is not None:
variation_category_item_list.append(current_category) variation_category_item_list.append(start_with_item)
variation_category_list = self.getVariationCategoryList(base_category_list=base_category_list) variation_category_list = self.getVariationCategoryList(base_category_list=base_category_list)
for variation_category in variation_category_list: for variation_category in variation_category_list:
resource = self.portal_categories.resolveCategory(variation_category) resource = self.portal_categories.resolveCategory(variation_category)
...@@ -85,7 +87,7 @@ class Variated(Base): ...@@ -85,7 +87,7 @@ class Variated(Base):
else: else:
index = variation_category.find('/') + 1 index = variation_category.find('/') + 1
label = variation_category[index:] label = variation_category[index:]
variation_category_item_list.append((value, label)) variation_category_item_list.append((label, label)) # We do not know if value is on left or right
return variation_category_item_list return variation_category_item_list
security.declareProtected(Permissions.ModifyPortalContent, '_setVariationCategoryList') security.declareProtected(Permissions.ModifyPortalContent, '_setVariationCategoryList')
...@@ -127,7 +129,7 @@ class Variated(Base): ...@@ -127,7 +129,7 @@ class Variated(Base):
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getVariationRangeBaseCategoryItemList') 'getVariationRangeBaseCategoryItemList')
def getVariationRangeBaseCategoryItemList(self, base=1, method_id='getTitle', current_category=None): def getVariationRangeBaseCategoryItemList(self, base=1, method_id='getTitle', start_with_item=None):
""" """
Returns possible variations of the resource Returns possible variations of the resource
as a list of tuples (id, title). This is mostly as a list of tuples (id, title). This is mostly
...@@ -188,9 +190,6 @@ class Variated(Base): ...@@ -188,9 +190,6 @@ class Variated(Base):
clist = [(None,None)] clist = [(None,None)]
return clist return clist
# Missing methods
# getVariationBaseCategoryItemList
# Help # Help
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getMatrixVariationRangeBaseCategoryList') 'getMatrixVariationRangeBaseCategoryList')
......
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
<hidden type="int">0</hidden> <hidden type="int">0</hidden>
<jump_method>base_jump_relation</jump_method> <jump_method>base_jump_relation</jump_method>
<max_length></max_length> <max_length></max_length>
<portal_type type="list">[('Sale Packing List', 'Sale Packing List')]</portal_type> <portal_type type="list">[('Sale Packing List', 'Sale Packing List'), ('Sales Packing List', 'Sales Packing List')]</portal_type>
<required type="int">0</required> <required type="int">0</required>
<title>Packing List</title> <title>Packing List</title>
<truncate type="int">0</truncate> <truncate type="int">0</truncate>
...@@ -408,4 +408,4 @@ ...@@ -408,4 +408,4 @@
</fields> </fields>
</group> </group>
</groups> </groups>
</form> </form>
\ No newline at end of file
...@@ -103,7 +103,10 @@ try: ...@@ -103,7 +103,10 @@ try:
o = context.restrictedTraverse(url) o = context.restrictedTraverse(url)
v.update(gv) v.update(gv)
o.edit(**v) o.edit(**v)
o.flushActivity(invoke = 1) # This is required if we wish to provide immediate display o.flushActivity(method_id="immediateReindexObject",
invoke = 1) # This is required if we wish to provide immediate display
o.flushActivity(method_id="recursiveImmediateReindexObject",
invoke = 1) # Requires if we want to display indexed subobject data... but long
# However it seems it reindexed many many times... XXX # However it seems it reindexed many many times... XXX
# Maybe we should build a list of objects we need # Maybe we should build a list of objects we need
# Update basic attributes # Update basic attributes
......
...@@ -58,7 +58,7 @@ try: ...@@ -58,7 +58,7 @@ try:
#if f.get_value('base_category') == base_category: #if f.get_value('base_category') == base_category:
k = f.id k = f.id
v = getattr(request,k,None) v = getattr(request,k,None)
if v in (None, '', 'None', []) and context.getProperty(k[3:]) in (None, '', 'None', []): if v in (None, '', 'None', [], ()) and context.getProperty(k[3:]) in (None, '', 'None', [], ()):
# The old value is None and the new value is not significant # The old value is None and the new value is not significant
# This bug fix is probably temporary since '' means None # This bug fix is probably temporary since '' means None
pass pass
...@@ -108,7 +108,7 @@ try: ...@@ -108,7 +108,7 @@ try:
uids, uids,
object_uid) object_uid)
elif len(relation_list) > 0: elif len(relation_list) > 0:
# If we have only one in the list, we don't want to lost our time by # If we have only one in the list, we don't want to lose our time by
# selecting it. So we directly do the update # selecting it. So we directly do the update
if len(relation_list) == 1: if len(relation_list) == 1:
selection_index=None selection_index=None
......
...@@ -2,7 +2,24 @@ ...@@ -2,7 +2,24 @@
import string import string
doAction = favorite_select.split() #doAction = favorite_select.split() Previous implementation
if favorite_select.find('local_roles=') > 0:
# Some local roles are defined
url_items = favorite_select.split('&') # split parameters
new_items = []
for item in url_items:
if item.find('local_roles=') >= 0:
local_roles = item[item.find('local_roles='):].split(';')
for role in local_roles:
role = role.split('=')
if len(role[len(role)-1]) > 0:
new_items.append("local_roles:list=%s" % role[len(role)-1])
else:
new_items.append(item)
favorite_select = '&'.join(new_items)
doAction = (favorite_select,)
doAction0 = doAction[0] doAction0 = doAction[0]
request = context.REQUEST request = context.REQUEST
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from Products.Formulator.Errors import ValidationError, FormValidationError from Products.Formulator.Errors import ValidationError, FormValidationError
request=context.REQUEST request=context.REQUEST
try: try:
# Validate the form # Validate the form
form = getattr(context,dialog_id) form = getattr(context,dialog_id)
......
...@@ -56,7 +56,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -56,7 +56,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<img src="/images/pro/images/sepacla.png" alt="|"/>&nbsp; <img src="/images/pro/images/sepacla.png" alt="|"/>&nbsp;
<span tal:condition="print_actions"> <span tal:condition="print_actions">
<a href="print" <a href="print"
tal:attributes="href python:print_actions[0]['url']"> tal:attributes="href python:print_actions[0]['url']
+ '?selection_name=%s&dialog_category=%s&form_id=%s'
% (selection_name , 'object_print', form_id) ">
<img src="/images/pro/images/print.png" title="Print" width="22" height="22" <img src="/images/pro/images/print.png" title="Print" width="22" height="22"
alt="Print" border="0"/> alt="Print" border="0"/>
</a>&nbsp; </a>&nbsp;
......
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
<list_action>folder_contents</list_action> <list_action>folder_contents</list_action>
<list_method type="method">searchFolder</list_method> <list_method type="method">searchFolder</list_method>
<meta_types type="list">[]</meta_types> <meta_types type="list">[]</meta_types>
<portal_types type="list">[]</portal_types> <portal_types type="list">[('Sale Invoice Transaction Line','Sale Invoice Transaction Line')]</portal_types>
<report_root_list type="list">[]</report_root_list> <report_root_list type="list">[]</report_root_list>
<report_tree type="int">0</report_tree> <report_tree type="int">0</report_tree>
<search type="int">0</search> <search type="int">0</search>
...@@ -326,4 +326,4 @@ ...@@ -326,4 +326,4 @@
</fields> </fields>
</group> </group>
</groups> </groups>
</form> </form>
\ No newline at end of file
...@@ -1014,8 +1014,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1014,8 +1014,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
list_body += '<td class="Data">&nbsp;</td>' list_body += '<td class="Data">&nbsp;</td>'
list_body += '</tr>' list_body += '</tr>'
list_html = header + selection_line + list_header + \ list_html = header + selection_line + list_header + list_search + list_body + footer
list_search + list_body + footer
#Create DomainTree Selector and DomainTree box #Create DomainTree Selector and DomainTree box
......
...@@ -132,6 +132,8 @@ class PDFTemplate(ZopePageTemplate): ...@@ -132,6 +132,8 @@ class PDFTemplate(ZopePageTemplate):
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
doc_xml = ZopePageTemplate.__call__(self, *args, **kwargs) doc_xml = ZopePageTemplate.__call__(self, *args, **kwargs)
batch_mode = kwargs.get('batch_mode', 0)
request = kwargs.get('REQUEST', None) request = kwargs.get('REQUEST', None)
if not request: if not request:
request = get_request() request = get_request()
...@@ -141,7 +143,7 @@ class PDFTemplate(ZopePageTemplate): ...@@ -141,7 +143,7 @@ class PDFTemplate(ZopePageTemplate):
report_tool = getToolByName(self, 'portal_report') report_tool = getToolByName(self, 'portal_report')
pdf = report_tool.renderPDF(self.pdf_stylesheet, doc_xml, context=self.pt_getContext()['here'], *args, **kwargs) pdf = report_tool.renderPDF(self.pdf_stylesheet, doc_xml, context=self.pt_getContext()['here'], *args, **kwargs)
if request: if request and not batch_mode:
request.RESPONSE.setHeader('Content-Type','application/pdf') request.RESPONSE.setHeader('Content-Type','application/pdf')
request.RESPONSE.setHeader('Content-Length',len(pdf)) request.RESPONSE.setHeader('Content-Length',len(pdf))
request.RESPONSE.setHeader('Content-Disposition','inline;filename=%s.pdf' % self.id) request.RESPONSE.setHeader('Content-Disposition','inline;filename=%s.pdf' % self.id)
......
...@@ -69,6 +69,14 @@ class SelectionTool( UniqueObject, SimpleItem ): ...@@ -69,6 +69,14 @@ class SelectionTool( UniqueObject, SimpleItem ):
, 'manage_overview' ) , 'manage_overview' )
manage_overview = DTMLFile( 'explainCategoryTool', _dtmldir ) manage_overview = DTMLFile( 'explainCategoryTool', _dtmldir )
security.declareProtected(ERP5Permissions.View, 'callSelectionFor')
def callSelectionFor(self, selection_name, context=None, REQUEST=None):
if context is None: context = self
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is None:
return None
return selection(context=context)
security.declareProtected(ERP5Permissions.View, 'getSelectionFor') security.declareProtected(ERP5Permissions.View, 'getSelectionFor')
def getSelectionFor(self, selection_name, REQUEST=None): def getSelectionFor(self, selection_name, REQUEST=None):
""" """
......
...@@ -62,6 +62,7 @@ ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile ...@@ -62,6 +62,7 @@ ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile
############################################################################## ##############################################################################
# Properties # Properties
from OFS.PropertyManager import PropertyManager, type_converters from OFS.PropertyManager import PropertyManager, type_converters
from OFS.PropertyManager import escape
class ERP5PropertyManager(PropertyManager): class ERP5PropertyManager(PropertyManager):
...@@ -173,6 +174,7 @@ PropertyManager.propertyValues = ERP5PropertyManager.propertyValues ...@@ -173,6 +174,7 @@ PropertyManager.propertyValues = ERP5PropertyManager.propertyValues
PropertyManager.propertyItems = ERP5PropertyManager.propertyItems PropertyManager.propertyItems = ERP5PropertyManager.propertyItems
PropertyManager._propertyMap = ERP5PropertyManager._propertyMap PropertyManager._propertyMap = ERP5PropertyManager._propertyMap
PropertyManager.propdict = ERP5PropertyManager.propdict PropertyManager.propdict = ERP5PropertyManager.propdict
PropertyManager.hasProperty = ERP5PropertyManager.hasProperty
############################################################################## ##############################################################################
......
...@@ -522,7 +522,7 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base): ...@@ -522,7 +522,7 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
else: else:
kw['query'] = join(query, ' AND ') kw['query'] = join(query, ' AND ')
LOG("Search Query Args:",0,str(kw)) #LOG("Search Query Args:",0,str(kw))
# Compute "sort_index", which is a sort index, or none: # Compute "sort_index", which is a sort index, or none:
if kw.has_key('sort-on'): if kw.has_key('sort-on'):
......
...@@ -58,7 +58,7 @@ class ZSQLBrain(Acquisition.Implicit): ...@@ -58,7 +58,7 @@ class ZSQLBrain(Acquisition.Implicit):
"""Try to return the object for this record""" """Try to return the object for this record"""
try: try:
obj = self.aq_parent.unrestrictedTraverse(self.getPath()) obj = self.aq_parent.unrestrictedTraverse(self.getPath())
if not obj: if obj is None:
if REQUEST is None: if REQUEST is None:
REQUEST = self.REQUEST REQUEST = self.REQUEST
obj = self.aq_parent.portal_catalog.resolve_url(self.getPath(), REQUEST) obj = self.aq_parent.portal_catalog.resolve_url(self.getPath(), REQUEST)
...@@ -72,3 +72,19 @@ class ZSQLBrain(Acquisition.Implicit): ...@@ -72,3 +72,19 @@ class ZSQLBrain(Acquisition.Implicit):
returns the path stored in the Catalog returns the path stored in the Catalog
""" """
return self.path return self.path
def resolve_url(self, path, REQUEST):
"""
Taken from ZCatalog
Attempt to resolve a url into an object in the Zope
namespace. The url may be absolute or a catalog path
style url. If no object is found, None is returned.
No exceptions are raised.
"""
script=REQUEST.script
if string.find(path, script) != 0:
path='%s/%s' % (script, path)
try: return REQUEST.resolve_url(path)
except: pass
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