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):
, PropertySheet.Movement
, PropertySheet.Amount
, PropertySheet.Reference
, PropertySheet.TradeCondition
, PropertySheet.PaymentCondition
, PropertySheet.Comment
)
# Factory Type Information
......
......@@ -155,4 +155,24 @@ Un item sert a assurer la tracabilite des choses dans ERP5."""
sub_quantity = 0
for sub_item in sub_item_list :
sub_quantity += sub_item.getQuantity()
return self.getQuantity() - sub_quantity
\ No newline at end of file
return self.getQuantity() - sub_quantity
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..."""
"""
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.test(context):
return pri.getProperty('pri')
return None
def _updateIndustrialPrice(self):
pass
#self.modele_compute_pri(batch_mode=1)
......@@ -7,4 +7,20 @@
##parameters=
##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 @@
##parameters=
##title=
##
selection = context.portal_selections.getSelectionFor('purchase_packing_list_selection',REQUEST=context.REQUEST)
delivery_list = selection(context=context)
request = context.REQUEST
# Collect movements in Zero Stock applied rule
zs_movement_list = [context.portal_simulation.zero_stock['modele-137H401_coloris-modele-137H401-1_taille-adulte-52']]
for delivery_item in delivery_list:
delivery = delivery_item.getObject()
# keep only movements with a Modele resource
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 :
order_list = delivery.getCausalityValueList()
if len(order_list) > 0 :
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)
# Parse movements into a root group
root_group = context.portal_simulation.collectMovement(movement_list)
order_list = context.portal_simulation.buildOrderList(root_group)
return 'fait'
# update produced orders
for order in order_list:
order.autoPlan()
order.purchase_order_apply_condition()
return "fait"
<dtml-comment>
title:
connection_id:MySQL
max_rows:1000
max_cache:100
max_rows:100000
max_cache:0
cache_time:0
class_name:
class_file:
</dtml-comment>
<params>section
strict_membership</params>
<params></params>
SELECT DISTINCT
movement.resource_uid,
catalog.relative_url AS resource_relative_url,
movement.variation_text
FROM
movement, stock, catalog as section, category
WHERE
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
movement LEFT JOIN catalog ON (catalog.uid = movement.resource_uid)
\ No newline at end of file
......@@ -8,16 +8,18 @@ class_name:
class_file:
</dtml-comment>
<params></params>
# Host:
# Database: test
# Table: 'stock'
#
CREATE TABLE `message` (
`uid` int(11) NOT NULL auto_increment,
`path` VARCHAR(255),
`method_id` VARCHAR(40),
`processing_node` INT DEFAULT -1,
`processing` INT DEFAULT 0,
`priority` INT DEFAULT 0,
`message` BLOB,
`processing_node` INT DEFAULT NULL,
PRIMARY KEY (`uid`),
KEY `path` (`path`),
KEY `processing_node` (`processing_node`),
KEY `method_id` (`method_id`),
) TYPE = InnoDB;
\ No newline at end of file
KEY `processing_node` (`processing_node`),
KEY `processing` (`processing`),
KEY `priority` (`priority`),
) TYPE = InnoDB;
......@@ -7,11 +7,9 @@ cache_time:0
class_name:
class_file:
</dtml-comment>
<params>path
method_id</params>
<params>uid:list</params>
DELETE FROM
message
message
WHERE
path = <dtml-sqlvar path type="string">
<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
\ No newline at end of file
<dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else> OR </dtml-if>
</dtml-in>
\ No newline at end of file
<dtml-comment>
title:
connection_id:MySQL
max_rows:1000
max_cache:100
max_rows:1
max_cache:0
cache_time:0
class_name:
class_file:
</dtml-comment>
<params>path
method_id
processing_node</params>
<params>uid</params>
UPDATE message
SET processing_node=<dtml-sqlvar processing_node type="int">
SET processing=1
WHERE
path = <dtml-sqlvar path type="string">
<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
\ No newline at end of file
<dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else>
OR </dtml-if></dtml-in>
\ No newline at end of file
......@@ -7,8 +7,14 @@ cache_time:0
class_name:
class_file:
</dtml-comment>
<params></params>
<params>processing_node
priority</params>
SELECT * FROM
message
WHERE
processing_node is NULL
\ No newline at end of file
message
WHERE
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>
ORDER BY
priority
\ No newline at end of file
......@@ -8,12 +8,16 @@ class_name:
class_file:
</dtml-comment>
<params>path
method_id</params>
method_id
processing_node
priority</params>
SELECT * FROM
message
<dtml-if "path or method_id">
message
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>
\ No newline at end of file
GROUP BY
path, method_id, processing_node, processing
\ No newline at end of file
......@@ -9,7 +9,13 @@ class_file:
</dtml-comment>
<params>path
method_id
message</params>
message
priority</params>
INSERT INTO message
VALUES
(<dtml-sqlvar path type="string">,<dtml-sqlvar method_id type="string">,<dtml-sqlvar message type="string">,NULL);
\ No newline at end of file
SET
path = <dtml-sqlvar path type="string">,
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:
action_list = o.portal_workflow.getActionsFor(o)
action_list = filter(lambda x:x.has_key('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:
o.portal_workflow.doActionFor(
o,
......
......@@ -11,7 +11,7 @@ class_file:zsqlbrain.py
variante_id_list=""
sort_on
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
<dtml-if expr="_.len(resource_id_list)>0">
, catalog AS resource
......
......@@ -20,6 +20,10 @@ 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)
WHERE item.portal_type = "Piece Tissu"
AND stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()">
AND stock.quantity < 0
\ No newline at end of file
AND stock.quantity < 0
AND movement.inventory IS NULL
\ No newline at end of file
......@@ -17,6 +17,23 @@ SELECT DISTINCT
item.uid, item.id, item.path, item.Description, item.simulation_state, item.default_destination_title
FROM
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">
, catalog AS resource
, category AS cat1
......@@ -26,9 +43,15 @@ FROM
, category AS cat2
</dtml-if>
WHERE item.portal_type = "Piece Tissu"
<dtml-in PieceTissu_searchConsumedList>AND item.uid <> <dtml-sqlvar uid type="int">
WHERE
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>
AND next_movement.uid is NULL
<dtml-if expr="_.len(resource_id_list)>0">
AND ( resource.id LIKE "<dtml-var expr="resource_id_list[0]">"
......
<dtml-comment>
title:
connection_id:MySQL
max_rows:1000
max_rows:750
max_cache:100
cache_time:0
class_name:ZSQLBrain
......@@ -15,17 +15,15 @@ resource_uid</params>
SELECT
catalog.*
FROM
catalog, movement, category, stock, catalog as movement_c
catalog, movement, category, stock
WHERE
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 movement.is_accountable = 1
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.variation_text = <dtml-sqlvar variation_text type="string">
AND stock.node_uid = <dtml-sqlvar node_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 :
corresp_variation_list = [movement.getTaille()]+['value']
# find taille_client
line_taille_client = ' '
correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
if len(correspondance_list) == 1 :
my_correspondance = correspondance_list[0]
mapped_value_list = my_correspondance.objectValues()
for mapped_value in mapped_value_list :
if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) :
line_taille_client = mapped_value.getProperty(key='taille_client')
break
line_taille_client = movement.Amount_getTailleClient()
# correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
# if len(correspondance_list) == 1 :
# my_correspondance = correspondance_list[0]
# mapped_value_list = my_correspondance.objectValues()
# for mapped_value in mapped_value_list :
# if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) :
# line_taille_client = mapped_value.getProperty(key='taille_client')
# break
try :
line_quantity = float(movement.getProperty(key='quantity'))
......@@ -78,21 +79,22 @@ if resource <> None :
line_date = order_line.aq_parent.getStopDate()
# find code_article
line_code_article = ''
variated_reference_list = resource.contentValues(filter={'portal_type':'Variated Reference'})
# we search a variated_reference wich define 'code_article'
my_variated_reference = None
for variated_reference in variated_reference_list :
if len(variated_reference.getMappedValuePropertyList()) <> 0 :
if variated_reference.getMappedValuePropertyList()[0] == 'code_article' :
my_variated_reference = variated_reference
break
if my_variated_reference is not None :
mapped_value_list = my_variated_reference.objectValues()
for mapped_value in mapped_value_list :
if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) :
line_code_article = mapped_value.getProperty(key='code_article')
break
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'
# my_variated_reference = None
# for variated_reference in variated_reference_list :
# if len(variated_reference.getMappedValuePropertyList()) <> 0 :
# if variated_reference.getMappedValuePropertyList()[0] == 'code_article' :
# my_variated_reference = variated_reference
# break
# if my_variated_reference is not None :
# mapped_value_list = my_variated_reference.objectValues()
# for mapped_value in mapped_value_list :
# if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) :
# line_code_article = mapped_value.getProperty(key='code_article')
# break
line_items = [line_resource,line_coloris,line_morphologie,line_taille,
line_taille_client,line_quantity,line_date,line_code_article]
......
......@@ -18,7 +18,7 @@ try:
if 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)
for product_item in product_raw_list :
product_list.append(product_item.title)
......
......@@ -28,6 +28,10 @@ try :
if line.find(text_list[0]) <> (-1) : # quantity
# 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 :
compteur += 1
new_id = str(my_container.generateNewId(default = 40000))
......
......@@ -58,7 +58,9 @@ try :
except :
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
new_id = str(item.generateNewId(default = 40000))
item.portal_types.constructContent(type_name = 'Piece Tissu',
......@@ -81,11 +83,11 @@ try :
movement_list[0].setItemIdList(new_aggregated_item_id_list)
compteur += 1
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 :
error_item_list.append(id_and_weight_list[i*2]+'(non sortie ou plusieurs sorties)')
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 :
error_item_list.append(id_and_weight_list[i*2]+'(inconnue)')
......
......@@ -86,7 +86,7 @@
<values>
<alternate_name></alternate_name>
<css_class></css_class>
<default>Delivery_zSearchResource</default>
<default>PieceTissu_zGetAvailableItemList</default>
<description></description>
<display_maxwidth></display_maxwidth>
<display_width type="int">20</display_width>
......@@ -95,7 +95,7 @@
<hidden type="int">1</hidden>
<max_length></max_length>
<required type="int">0</required>
<title></title>
<title>x</title>
<truncate type="int">0</truncate>
</values>
<tales>
......
# 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)
## Script (Python) "PortalSimulation_activateRequirementList"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##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_id_list = map(lambda x:x.id,order_list)
object_id_list = context.commande_achat.objectIds()
order_id_list = filter(lambda x: x in object_id_list, order_id_list)
context.commande_achat.deleteContent(order_id_list)
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)
object_id_list = context.commande_achat.objectIds()
order_id_list = filter(lambda x: x in object_id_list, order_id_list)
context.commande_achat.deleteContent(order_id_list)
#return "Done"
# Stock sourcing states
#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
source_state_list = None
source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'started', 'stopped', 'delivered', 'invoiced')
#source_state_list = None
# Get inventory list
inventory_list = context.SimulationTool_getGroupFutureInventoryList(simulation_state=source_state_list)
......@@ -28,9 +40,9 @@ for inventory_item in inventory_list:
if movement is not None:
resource = movement.getResourceValue()
if resource is not None:
# Only source negative stock
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)
if resource.getPortalType() != "Assortiment":
# Only source negative stock
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
......@@ -7,21 +7,20 @@
##parameters=resource=None
##title=
##
from Products.ERP5Type.Document import newTempMovement
from Products.ERP5.Document import newTempMovement
from DateTime import DateTime
# Stock sourcing states
#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
source_state_list = None
source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
#source_state_list = None
# Default date
now_date = DateTime()
now_date = DateTime(DateTime().Date())
# Get inventory list
inventory_list = context.SimulationTool_getGroupFutureInventoryList(resource=resource, simulation_state=source_state_list)
# Commit SQL
# context.portal_simulation.commitTransaction()
context.portal_simulation.commitTransaction()
# First, find out which resources are missing
# and build a dictionnary of quantity, variation
......@@ -40,7 +39,7 @@ for inventory_item in inventory_list:
#LOG('ZeroStockRule WARNING',0,'None movement found')
# Commit SQL
# context.portal_simulation.commitTransaction()
context.portal_simulation.commitTransaction()
# A list of resources to create
to_create = quantity_dict.keys()
......@@ -93,4 +92,4 @@ for order in order_list:
order.autoPlan()
order.purchase_order_apply_condition()
return printed
\ No newline at end of file
return printed
......@@ -7,24 +7,12 @@
##parameters=
##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(
"modele/417P401",
"""coloris/modele/417P401/1_espace_stuc
taille/enfant/10 ans""",
"group/Coramy",
"site/Stock_PF"
)
for i in result:
......
......@@ -23,9 +23,11 @@ omit_simulation
omit_input
omit_output
simulation_state
query</params>
query
calculate_asset:int=0</params>
SELECT
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.relative_url AS node_relative_url,
section.title AS section_title,
......
......@@ -7,7 +7,9 @@ cache_time:0
class_name:ZSQLBrain
class_file:zsqlbrain.py
</dtml-comment>
<params>to_date</params>
<params>to_date
resource
simulation_state:list</params>
SELECT
SUM(stock.quantity) as inventory,
section.title AS section_title,
......@@ -29,7 +31,9 @@ AND stock.section_uid = section_category.uid
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()">)
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>
GROUP BY
resource.uid, movement.variation_text
......
......@@ -7,28 +7,35 @@
##parameters=
##title=
##
if 1:
return context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
if 0:
# Delete all proposed orders
for o in context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()]) :
realo = o.getObject()
realo.aq_parent.deleteContent(realo.getId())
#production_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
#context.ordre_fabrication.deleteContent(map(lambda b:b.id, production_list))
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
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)
# 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
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
movement_list = []
for movement in zs_movement_list[0:100] :
for movement in zs_movement_list:
resource_value = movement.getResourceValue()
if resource_value is not None:
#if resource_value.getPortalType() == 'Modele' :
movement_list.append(movement)
# Parse movements into a root group
......@@ -40,6 +47,9 @@ for order in order_list:
order.autoPlan()
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
context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
......
......@@ -15,10 +15,10 @@
<field><id>listbox</id> <type>ListBox</type>
<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>
<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>
<default></default>
<default_params type="list">[('id', "''")]</default_params>
......@@ -31,7 +31,7 @@
<hidden type="int">0</hidden>
<lines type="int">30</lines>
<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>
<portal_types type="list">[('Piece Tissu', 'Piece Tissu')]</portal_types>
<report_root_list type="list">[]</report_root_list>
......@@ -45,6 +45,7 @@
<title>Pices de tissu</title>
</values>
<tales>
<list_method>python:here.getPortalObject().portal_skins.local_list_method[here.REQUEST.list_method_id]</list_method>
</tales>
<messages>
<message name="external_validator_failed">The input failed the external validator.</message>
......
......@@ -114,6 +114,30 @@
<message name="not_float">You did not enter a floating point number.</message>
</messages>
</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>
<values>
<alternate_name></alternate_name>
......
......@@ -4,7 +4,7 @@
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=transformation=None, quantities=1
##parameters=
##title=
##
transformed_component = context
......@@ -14,9 +14,8 @@ variation_base_category_list = []
q_variation_base_category_list = transformed_component.getQVariationBaseCategoryList()
v_variation_base_category_list = transformed_component.getVVariationBaseCategoryList()
if quantities :
for base_category in q_variation_base_category_list :
variation_base_category_list.append(base_category)
for base_category in q_variation_base_category_list :
variation_base_category_list.append(base_category)
for base_category in v_variation_base_category_list :
if not base_category in variation_base_category_list :
......@@ -26,7 +25,7 @@ variation_base_category_list.sort()
variation_list_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)
cartesian_variation_list = context.cartesianProduct(variation_list_list)
......@@ -55,14 +54,6 @@ for variation_list in cartesian_variation_list :
pretty_variation_2 = '- '
for my_variation in variation :
pretty_variation_2 += my_variation+' - '
if 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])
correspondance_list.append([pretty_variation_1, quantity, pretty_variation_2])
return correspondance_list
......@@ -90,7 +90,7 @@
<tr>
<td colspan="3" >
<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">
<td>
<span tal:repeat="variation_item python:transformed_resource.getVariationCategoryList()">
......
......@@ -47,6 +47,8 @@ elif local_user == 'Jocelyne_Olejarz' :
printer_name = 'Meto_XS40_4'
elif local_user == 'Nathalie_Wadoux' :
printer_name = 'Meto_XS40_5'
elif local_user == 'Chantal_Hannequin' :
printer_name = 'Meto_XS40_6'
else :
printer_name = 'Meto_XS40_2'
......
......@@ -22,6 +22,8 @@ elif local_user == 'Jocelyne_Olejarz' :
printer_name = 'Meto_XS40_4'
elif local_user == 'Nathalie_Wadoux' :
printer_name = 'Meto_XS40_5'
elif local_user == 'Chantal_Hannequin' :
printer_name = 'Meto_XS40_6'
else :
printer_name = 'Meto_XS40_2'
......
......@@ -21,7 +21,7 @@ def decoupe(s,width):
result = s[-width:]
else:
#result = string.ljust(s,width)
result = (' ' * (width-len(s))) + s
result = s + (' ' * (width-len(s)))
#return ' '+s
return result
......
......@@ -20,8 +20,8 @@ def category_property(category, property):
else :
return " "
for taille in taille_list :
my_taille = 'taille/'+taille
if len(taille_list) == 0 :
my_taille = None
if coloris is not None and morphologie is not None :
my_coloris = 'coloris/'+coloris
my_morphologie = 'morphologie/'+morphologie
......@@ -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"))
else :
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
......@@ -31,7 +31,10 @@ for container_item in container_list :
ligne_container += str(container.getGrossWeight())+tab
ligne_container += first_line.getResourceValue().getId()+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 += "Maillot de bain"+tab
ligne_container += first_line.Amount_getCodeArticleClient()+tab
......
......@@ -10,16 +10,34 @@
allowsplitting="1"
tal:define="packing_list python:here.getCausalityValueList(portal_type=['Sale Packing List','Sales Packing List'])[0];
invoice_id python:here.getId();
invoice_reference python: here.getReference(0);
resource_title python:here.getResourceTitle() or 'Euros';
resource_id python:here.getResourceId() or 'EUR';
income python: here.income;
vat python: here.vat;
payable python: here.payable;">
income python: here.Invoice_zGetTotalNetPrice();
vat python: here.Invoice_zGetTotalVat();
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:define="destination python: packing_list.getDestinationValue();
destination_administration python: packing_list.getDestinationAdministrationValue() or packing_list.getDestinationSectionValue();
start_date python:packing_list.getStartDate();
tal:define="destination python: here.getDestinationValue();
destination_administration python: here.getDestinationAdministrationValue() or here.getDestinationSectionValue();
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();
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];">
<stylesheet>
......@@ -78,7 +96,8 @@
<stylecmd expr="('RIGHTPADDING', (0,0), (-1,-1), 5)"/>
<stylecmd expr="('TOPPADDING', (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="('BOX', (0,0), (-1,-1), 0, colors.white)"/>
<stylecmd expr="('FONT', (0,0), (-1,-1), 'Helvetica', 8)"/>
......@@ -132,7 +151,7 @@
</stylesheet>
<pagetemplate id="FirstPage" nextid="Page" startframe="content">
<pagetemplate id="FirstPage" nextid="SecondPage" startframe="content">
<static>
<!-- Entete CORAMY -->
......@@ -159,21 +178,21 @@
<!-- 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_id">
Facture n 105 915
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 9/07/03
Gravelines, le XXX
</infostring>
<infostring align="left" x="18.5cm" y="26cm" size="8"
font="Helvetica-Bold" color="(0,0,0)">
Folio 1
Folio %(page)s
</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="1cm" y1="25cm" y2="4cm" width="1"/>
<line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/>
......@@ -195,7 +214,7 @@
</infostring>
<infostring align="center" x="2.5cm" y="24.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: order.getDestinationReference()">
7286007
DestinationReference XXX
</infostring>
<infostring align="left" x="1.7cm" y="23.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
......@@ -206,7 +225,7 @@
</infostring>
<infostring align="center" x="2.5cm" y="23.3cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: order.getId()">
119 022
Order.id XXX
</infostring>
<infostring align="left" x="1.1cm" y="22.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
......@@ -217,33 +236,23 @@
</infostring>
<infostring align="center" x="2.5cm" y="22.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: packing_list_id">
108 301
PackingListId XXX
</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
</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
</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
</infostring>
<infostring align="left" x="3.5cm" y="21.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
32
</infostring>
<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 align="center" x="2.5cm" y="21.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: container_number">
NbrColis XXX
</infostring>
<infostring align="left" x="6cm" y="24.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Livraison / Versand / Delivery
</infostring>
......@@ -279,36 +288,30 @@
</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
</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
</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
</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
</infostring>
<infostring align="left" x="4.3cm" y="20.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Device / Currency / Wahrung
</infostring>
<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 align="left" x="5.8cm" y="21cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: payment_mode ">
payment_modeXXX
</infostring>
<infostring align="left" x="8.5cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: resource_title">
Euros
<infostring align="left" x="5.8cm" y="20.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: '%i jours Net' % payment_term">
payment_termXXX
</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)">
Code comptable
......@@ -319,47 +322,50 @@
<infostring align="left" x="11.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Conditions d'escompte / Diskont / Discount.
</infostring>
<infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
41REDOU
<infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: code_comptable">
CodeComptable XXX
</infostring>
<infostring align="left" x="11.6cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
2,75 sous 20 jours
<infostring align="left" x="14cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
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 align="left" x="18.9cm" y="24.6cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Port / Porto
</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)">
<infostring align="left" x="18.9cm" y="24.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
Transporteur
</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
</infostring>
<infostring align="left" x="18.8cm" y="22.8cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
CORAMY
<infostring align="center" x="19.5cm" y="23.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
tal:content="python: delivery_mode">
delivery_modeXXX
</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
</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
</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
</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
</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
</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 -->
<rectangle x="1cm" y="19.9cm" width="19.5cm" height="0.4cm"
......@@ -368,15 +374,15 @@
<infostring align="left" x="2.8cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Denomination des produits
Dnomination des produits
</infostring>
<infostring align="left" x="10cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Repartition par tailles
Rpartition par tailles
</infostring>
<infostring align="left" x="15.4cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
Quantite
Quantit
</infostring>
<infostring align="left" x="17.1cm" y="20cm" size="9"
font="Helvetica-Oblique" color="(0,0,0)">
......@@ -409,10 +415,12 @@
font="Helvetica-Oblique" color="(0,0,0)">
T.V.A.
</infostring>
<infostring align="left" x="9.3cm" y="5.1cm" size="9"
font="Helvetica" color="(0,0,0)">
19,6%%
</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
......@@ -440,48 +448,249 @@
<infostring align="center" x="2.2cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % income.getSourceCredit()">
14 408,46
tal:content="python: '%.2f' % income">
income XXX
</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)">
14 408,46
</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)"
tal:content="python: '%.2f' % vat.getSourceCredit()">
2 824,06
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.getSourceDebit()">
17 232,52
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">
EUR
resource_id XXX
</infostring>
<infostring align="left" x="18cm" y="4.5cm" size="10"
font="Helvetica-Bold" color="(0,0,0)">
31/07/03
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 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 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 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 align="left" x="1.6cm" y="2.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
Nos marchandises sont grevees d'une clause de reserve de propriete, reprise dans nos conditions generales de venteindiquees au verso
<infostring align="center" x="2.2cm" y="4.5cm" size="9"
font="Helvetica" color="(0,0,0)"
tal:content="python: '%.2f' % income">
income XXX
</infostring>
<infostring align="left" x="4.5cm" y="2.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
Allegemeine Verkaufsbedingungen auf ruckseite - General sales conditions overleaf
<infostring align="center" x="3.8cm" y="4.5cm" size="9"
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>
</static>
......@@ -491,7 +700,7 @@
x="1cm"
y="5.8cm"
width="19.5cm"
height="14.1cm"
height="18.8cm"
leftpadding="0.1cm"
rightpadding="0.1cm"
toppadding="0.2cm"
......@@ -499,6 +708,10 @@
showBoundary="1"/>
</pagetemplate>
<pagetemplate id="Page" >
<static>
......@@ -522,4 +735,4 @@
</pagetemplate>
</tal:block>
</template>
</template>
\ No newline at end of file
......@@ -500,10 +500,10 @@
<field><id>listbox</id> <type>ListBox</type>
<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>
<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>
<default></default>
<default_params type="list">[]</default_params>
......
......@@ -15,10 +15,10 @@
<field><id>listbox</id> <type>ListBox</type>
<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>
<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>
<default></default>
<default_params type="list">[('id', "''")]</default_params>
......@@ -37,7 +37,7 @@
<report_root_list type="list">[]</report_root_list>
<report_tree type="int">0</report_tree>
<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>
<selection_name>order_selection</selection_name>
<sort type="list">[('id', 'id')]</sort>
......
......@@ -101,7 +101,7 @@
<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: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>
<TD align="right" tal:content="python: '%.0f' %totalizer[2]"/>
......@@ -112,7 +112,8 @@
<TR><!-- PAS DE COLORIS -->
<TD align="left"></TD>
<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"/>
<SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/>
</SPAN>
......
......@@ -116,17 +116,18 @@ class Amount(Base, Variated):
self._setVariationValue(variation_value)
self.reindexObject()
security.declareProtected(Permissions.AccessContentsInformation,
'getVariationRangeCategoryItemList')
'getVariationRangeCategoryItemList')
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.
the variation of the resource (not the variation range)
"""
try:
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:
# FIXME: method_name vs. method_id, start_with_item vs. start_with_empty, etc. -yo
return self.portal_categories.getCategoryChildItemList()
......@@ -294,7 +295,7 @@ class Amount(Base, Variated):
"""
quantity = self.getConvertedTargetQuantity()
efficiency = self.getTargetEfficiency()
if efficiency in (0, 0.0, None):
if efficiency in (0, 0.0, None, ''):
efficiency = 1.0
if quantity not in (None, ''):
return float(quantity) / efficiency
......@@ -425,6 +426,15 @@ class Amount(Base, Variated):
else:
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
security.declareProtected(Permissions.ModifyPortalContent, 'getLostQuantity')
def getLostQuantity(self):
......
......@@ -204,3 +204,17 @@ Une ligne tarifaire."""
more_result += container.getContainerText()
result = result + '\n'.join(map(lambda x: " %s" % x, more_result.split('\n')))
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."""
Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -270,7 +271,17 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -284,6 +295,8 @@ Une ligne tarifaire."""
quantity += object_item.getQuantity()
else :
quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setTargetQuantity(quantity)
......@@ -305,6 +318,30 @@ Une ligne tarifaire."""
else:
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
def getRelatedQuantity(self):
"""
......
......@@ -30,6 +30,8 @@ from Globals import InitializeClass, PersistentMapping
from Acquisition import aq_base, aq_inner, aq_parent, aq_self
from AccessControl import ClassSecurityInfo
from Products.ERP5.ERP5Globals import current_inventory_state_list
from Products.CMFCore.WorkflowCore import WorkflowAction
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
......@@ -137,9 +139,9 @@ Une ligne tarifaire."""
# Update consumption last
if item_id_list is not None:
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)
elif consumed_item_id_list is not None:
if consumed_item_id_list is not None :
self._setConsumedItemIdList(consumed_item_id_list)
security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' )
......@@ -180,6 +182,9 @@ Une ligne tarifaire."""
quantity = self._baseGetQuantity()
if quantity not in (0.0, 0, None):
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
resource_value = self.getResourceValue()
if resource_value is not None:
......@@ -189,10 +194,11 @@ Une ligne tarifaire."""
at_date = self.getStartDate(),
variation_text = self.getVariationText(),
node = self.getDestination(),
section = self.getDestinationSection())
section = self.getDestinationSection(),
simulation_state = current_inventory_state_list)
inventory = self.getInventory()
if inventory in (None, ''):
return None # Do not change inventory if no inventory value provided
if current_inventory in (None, ''):
current_inventory = 0.0
return self.getInventory() - current_inventory
return self.getInventory()
......@@ -216,6 +222,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity
in the inventory attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -229,7 +236,14 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -240,7 +254,7 @@ Une ligne tarifaire."""
quantity = 0
for object_item in item_object_list :
quantity += object_item.getQuantity()
quantity += object_item.getRemainingQuantity()
self.setInventory(quantity)
......@@ -252,11 +266,27 @@ Une ligne tarifaire."""
"""
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):
"""
Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -270,7 +300,17 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -290,6 +330,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -303,7 +344,17 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -315,6 +366,8 @@ Une ligne tarifaire."""
for object_item in item_object_list :
quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setConsumptionQuantity(quantity)
......@@ -335,3 +388,12 @@ Une ligne tarifaire."""
return self.getItemIdList()
else :
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."""
)
}
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')
def getTotalInventory(self):
"""
......@@ -153,7 +170,9 @@ Une ligne tarifaire."""
quantity = self._baseGetQuantity()
if quantity not in (0.0, 0, None):
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
resource_value = self.getResourceValue()
if resource_value is not None:
......@@ -166,8 +185,8 @@ Une ligne tarifaire."""
section = self.getDestinationSection(),
simulation_state = current_inventory_state_list)
inventory = self.getInventory()
if inventory in (None, ''):
return None # Do not change inventory if no inventory value provided
if current_inventory in (None, ''):
current_inventory = 0.0
return self.getInventory() - current_inventory
return self.getInventory()
else:
......@@ -229,6 +248,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity
in the inventory attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -242,7 +262,14 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -262,6 +289,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -275,7 +303,17 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -295,6 +333,7 @@ Une ligne tarifaire."""
Computes total_quantity of all given items and stores this total_quantity
in the quantity attribute of the cell
"""
previous_item_list = self.getAggregateValueList()
given_item_id_list = value
item_object_list = []
for item in given_item_id_list :
......@@ -308,7 +347,17 @@ Une ligne tarifaire."""
object = 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
self.setAggregateValueList(item_object_list)
......@@ -320,6 +369,8 @@ Une ligne tarifaire."""
for object_item in item_object_list :
quantity += object_item.getRemainingQuantity()
# we reset the location of the item
object_item.setLocation('')
self.setConsumptionQuantity(quantity)
......@@ -340,3 +391,35 @@ Une ligne tarifaire."""
return self.getItemIdList()
else :
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 @@
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.CMFCore.utils import getToolByName
from AccountingTransaction import AccountingTransaction
class Invoice(AccountingTransaction):
......@@ -55,6 +55,9 @@ class Invoice(AccountingTransaction):
, PropertySheet.Amount
, PropertySheet.Reference
, PropertySheet.PaymentCondition
, PropertySheet.ValueAddedTax
, PropertySheet.EcoTax
, PropertySheet.CopyrightTax
)
# CMF Factory Type Information
......@@ -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)."""
"""
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
security.declareProtected(Permissions.AccessContentsInformation, 'getAssetPrice')
def getAssetPrice(self, exclude_path_list = []):
security.declareProtected(Permissions.AccessContentsInformation, 'getSourceTotalAssetPrice')
def getSourceTotalAssetPrice(self):
"""
Returns a price which can be used to calculate stock value (asset)
"""
source_value = self.getSourceValue()
if not source_value:
# This is a production movement
return self.getIndustrialPrice()
if not source_value.isMemberOf('group/Coramy'):
# accountable price
return self.getPrice()
# This is an internal movement
current_asset_price = 0.0
current_inventory = 0.0
exclude_path_list.append(self.getRelativeUrl()) # Prevent infinite loops
for m in self.Movement_zGetPastMovementList(node_uid = self.getSourceUid(), section_uid = self.getDestinationUid(),
before_date = self.getStartDate()):
# 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):
try:
price = self.getSourceAssetPrice()
if price is None:
return None
quantity = self.getQuantity()
if quantity is None:
return None
return quantity * price
except:
return None
security.declareProtected(Permissions.AccessContentsInformation, 'getDestinationTotalAssetPrice')
def getDestinationTotalAssetPrice(self):
"""
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
security.declareProtected(Permissions.View, 'isConvergent')
......
......@@ -215,11 +215,50 @@ An order..."""
"""
Sets the order to ordered
(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()
# At confirm stage, we create deliveries for this order
self.activate().buildDeliveryList()
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')
def cancel(self):
"""
......
......@@ -30,6 +30,7 @@ from Globals import InitializeClass, PersistentMapping
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5.ERP5Globals import movement_type_list, draft_order_state
from Products.CMFCore.utils import getToolByName
from Delivery import Delivery
......
......@@ -406,7 +406,9 @@ a service in a public administration)."""
section=section,
node=node,
node_category=node_category,
section_category=section_category, **kw)
section_category=section_category,
simulation_state=simulation_state,
**kw)
return result
security.declareProtected(Permissions.AccessContentsInformation, 'getMovementHistoryStat')
......@@ -423,6 +425,7 @@ a service in a public administration)."""
section=section,
node=node,
node_category=node_category,
simulation_state=simulation_state,
section_category=section_category, **kw)
return result
......@@ -494,3 +497,23 @@ a service in a public administration)."""
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..."""
for transformation in transformation_list:
# Browse each transformed or assorted resource of the current transformation
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, \
total_variated_base_price, total_variated_source_base_price, duration \
= transformed_resource.getAggregatedAmountList(REQUEST)
......
......@@ -186,7 +186,7 @@ An ERP5 Rule..."""
source = source_section = 'role/Fournisseur'
destination_section = 'group/Coramy'
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,
target_stop_date = stop_date,
source = source,
......
......@@ -37,7 +37,7 @@ variation_type_list = ('Variation', 'Variante Tissu', 'Variante Modele',
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',
'Production Order', 'Purchase Order', 'Sale Order',
......@@ -63,6 +63,7 @@ delivery_type_list = ('Delivery',
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_id_list = variation_base_category_list # Temp Patch
invoice_movement_type_list = (
'Invoice Line',
......
......@@ -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 DateTime import DateTime
from ZTUtils import make_query
......@@ -52,7 +52,7 @@ class InventoryBrain(ZSQLBrain):
"""
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):
"""
......@@ -61,24 +61,15 @@ class InventoryBrain(ZSQLBrain):
at_date=DateTime()
current = self.getCurrentInventory()
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,
simulation_state = None)
simulation_state = reserved_inventory_state_list)
reserved_inventory = None
if len(result) > 0:
reserved_inventory = result[0].inventory
if reserved_inventory is None:
reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1,
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
return current + reserved_inventory
def getQuantityUnit(self, **kw):
try:
......@@ -123,7 +114,7 @@ class InventoryListBrain(ZSQLBrain):
"""
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):
"""
......@@ -132,28 +123,17 @@ class InventoryListBrain(ZSQLBrain):
at_date=DateTime()
current = self.getCurrentInventory()
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,
node=self.node_relative_url,
variation_text = self.variation_text,
simulation_state = None)
simulation_state = reserved_inventory_state_list)
reserved_inventory = None
if len(result) > 0:
reserved_inventory = result[0].inventory
if reserved_inventory is None:
reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
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
return current + reserved_inventory
def getQuantity(self, **kw):
result = self.Delivery_zGetTotal( resource_uid = [self.resource_uid],
......@@ -201,12 +181,27 @@ class InventoryListBrain(ZSQLBrain):
)
elif cname_id in ('getCurrentInventory',):
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,
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:
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))
except:
return ''
......@@ -231,13 +226,18 @@ class InventoryListBrain(ZSQLBrain):
if portal_type == "Simulation Movement":
order = o.getExplanationValue()
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:
LOG("Delivery Value",0,str(self.path))
delivery = o.getExplanationValue()
LOG("Delivery Value",0,str(delivery))
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"
class DeliveryListBrain(InventoryListBrain):
......@@ -274,42 +274,22 @@ class DeliveryListBrain(InventoryListBrain):
at_date=DateTime()
current = self.getCurrentInventory()
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,
variation_text = self.variation_text,
simulation_state = None)
simulation_state = reserved_inventory_state_list )
reserved_inventory = None
if len(result) > 0:
reserved_inventory = result[0].inventory
if reserved_inventory is None:
reserved_inventory = 0.0
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
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
return current + 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
current = self.getCurrentInventory()
result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
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
LOG("At Date",0,str(at_date))
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 Coordinate import Coordinate
from Entity import Entity
from Predicate import Predicate
from Coordinate import Coordinate
from Variated import Variated
\ No newline at end of file
......@@ -29,6 +29,7 @@
from Products.ERP5.Tool.SimulationTool import registerTargetSolver
from CopyToTarget import CopyToTarget
from zLOG import LOG
class SplitAndDefer(CopyToTarget):
"""
......
......@@ -67,15 +67,17 @@ class Variated(Base):
"""
return self._getVariationCategoryList(base_category_list = base_category_list)
security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList')
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 = []
if current_category is not None:
variation_category_item_list.append(current_category)
if start_with_item is not None:
variation_category_item_list.append(start_with_item)
variation_category_list = self.getVariationCategoryList(base_category_list=base_category_list)
for variation_category in variation_category_list:
resource = self.portal_categories.resolveCategory(variation_category)
......@@ -85,7 +87,7 @@ class Variated(Base):
else:
index = variation_category.find('/') + 1
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
security.declareProtected(Permissions.ModifyPortalContent, '_setVariationCategoryList')
......@@ -127,7 +129,7 @@ class Variated(Base):
security.declareProtected(Permissions.AccessContentsInformation,
'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
as a list of tuples (id, title). This is mostly
......@@ -188,9 +190,6 @@ class Variated(Base):
clist = [(None,None)]
return clist
# Missing methods
# getVariationBaseCategoryItemList
# Help
security.declareProtected(Permissions.AccessContentsInformation,
'getMatrixVariationRangeBaseCategoryList')
......
......@@ -138,7 +138,7 @@
<hidden type="int">0</hidden>
<jump_method>base_jump_relation</jump_method>
<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>
<title>Packing List</title>
<truncate type="int">0</truncate>
......@@ -408,4 +408,4 @@
</fields>
</group>
</groups>
</form>
\ No newline at end of file
</form>
......@@ -103,7 +103,10 @@ try:
o = context.restrictedTraverse(url)
v.update(gv)
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
# Maybe we should build a list of objects we need
# Update basic attributes
......
......@@ -58,7 +58,7 @@ try:
#if f.get_value('base_category') == base_category:
k = f.id
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
# This bug fix is probably temporary since '' means None
pass
......@@ -108,7 +108,7 @@ try:
uids,
object_uid)
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
if len(relation_list) == 1:
selection_index=None
......
......@@ -2,7 +2,24 @@
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]
request = context.REQUEST
......
......@@ -3,6 +3,7 @@
from Products.Formulator.Errors import ValidationError, FormValidationError
request=context.REQUEST
try:
# Validate the form
form = getattr(context,dialog_id)
......
......@@ -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;
<span tal:condition="print_actions">
<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"
alt="Print" border="0"/>
</a>&nbsp;
......
......@@ -209,7 +209,7 @@
<list_action>folder_contents</list_action>
<list_method type="method">searchFolder</list_method>
<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_tree type="int">0</report_tree>
<search type="int">0</search>
......@@ -326,4 +326,4 @@
</fields>
</group>
</groups>
</form>
\ No newline at end of file
</form>
......@@ -1014,8 +1014,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
list_body += '<td class="Data">&nbsp;</td>'
list_body += '</tr>'
list_html = header + selection_line + list_header + \
list_search + list_body + footer
list_html = header + selection_line + list_header + list_search + list_body + footer
#Create DomainTree Selector and DomainTree box
......
......@@ -132,6 +132,8 @@ class PDFTemplate(ZopePageTemplate):
def __call__(self, *args, **kwargs):
doc_xml = ZopePageTemplate.__call__(self, *args, **kwargs)
batch_mode = kwargs.get('batch_mode', 0)
request = kwargs.get('REQUEST', None)
if not request:
request = get_request()
......@@ -141,7 +143,7 @@ class PDFTemplate(ZopePageTemplate):
report_tool = getToolByName(self, 'portal_report')
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-Length',len(pdf))
request.RESPONSE.setHeader('Content-Disposition','inline;filename=%s.pdf' % self.id)
......
......@@ -69,6 +69,14 @@ class SelectionTool( UniqueObject, SimpleItem ):
, 'manage_overview' )
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')
def getSelectionFor(self, selection_name, REQUEST=None):
"""
......
......@@ -62,6 +62,7 @@ ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile
##############################################################################
# Properties
from OFS.PropertyManager import PropertyManager, type_converters
from OFS.PropertyManager import escape
class ERP5PropertyManager(PropertyManager):
......@@ -173,6 +174,7 @@ PropertyManager.propertyValues = ERP5PropertyManager.propertyValues
PropertyManager.propertyItems = ERP5PropertyManager.propertyItems
PropertyManager._propertyMap = ERP5PropertyManager._propertyMap
PropertyManager.propdict = ERP5PropertyManager.propdict
PropertyManager.hasProperty = ERP5PropertyManager.hasProperty
##############################################################################
......
......@@ -522,7 +522,7 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
else:
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:
if kw.has_key('sort-on'):
......
......@@ -58,7 +58,7 @@ class ZSQLBrain(Acquisition.Implicit):
"""Try to return the object for this record"""
try:
obj = self.aq_parent.unrestrictedTraverse(self.getPath())
if not obj:
if obj is None:
if REQUEST is None:
REQUEST = self.REQUEST
obj = self.aq_parent.portal_catalog.resolve_url(self.getPath(), REQUEST)
......@@ -72,3 +72,19 @@ class ZSQLBrain(Acquisition.Implicit):
returns the path stored in the Catalog
"""
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