From 5d10854e41a9c99717fe412255ab3ebb7cae3026 Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Fri, 23 Jan 2004 16:09:06 +0000 Subject: [PATCH] new git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@298 20353a03-c40f-0410-a6d1-a30d3c3de9de --- .../PortalSimulation_fixDeliveryRule.py | 37 ++ .../PortalSimulation_updateAssetPrice.py | 33 ++ .../coramy_mrp/ZeroStock_buildOrderList.py | 51 +++ .../skins/coramy_pdm/tissu_list_export.py | 31 ++ .../coramy_trade/ContainerLine_zGetTotal.zsql | 21 ++ .../coramy_trade/Container_oneClicInput.py | 121 +++++++ .../Container_oneClicInputForm.form | 195 +++++++++++ .../Container_printExtandLabel.py | 167 +++++++++ .../coramy_trade/Container_printLabel.py | 16 + .../coramy_trade/Container_sendExtandEdi.py | 93 +++++ .../Delivery_zGetNeededCellList.zsql | 30 ++ .../coramy_trade/InvoiceLine_priceView.form | 301 ++++++++++++++++ .../InvoiceLine_quantityView.form | 278 +++++++++++++++ .../skins/coramy_trade/InvoiceLine_view.form | 331 ++++++++++++++++++ .../PackingList_getDistinctContainerList.py | 44 +++ .../skins/coramy_trade/PlanTransportExtand.py | 111 ++++++ .../SaleInvoice_updateTransaction.py | 65 ++++ .../SalesPackingList_printForm.form | 41 +++ ...sales_packing_list_container_list_print.pt | 210 +++++++++++ 19 files changed, 2176 insertions(+) create mode 100755 product/Coramy/skins/coramy_mrp/PortalSimulation_fixDeliveryRule.py create mode 100755 product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py create mode 100755 product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py create mode 100755 product/Coramy/skins/coramy_pdm/tissu_list_export.py create mode 100755 product/Coramy/skins/coramy_trade/ContainerLine_zGetTotal.zsql create mode 100755 product/Coramy/skins/coramy_trade/Container_oneClicInput.py create mode 100755 product/Coramy/skins/coramy_trade/Container_oneClicInputForm.form create mode 100755 product/Coramy/skins/coramy_trade/Container_printExtandLabel.py create mode 100755 product/Coramy/skins/coramy_trade/Container_printLabel.py create mode 100755 product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py create mode 100755 product/Coramy/skins/coramy_trade/Delivery_zGetNeededCellList.zsql create mode 100755 product/Coramy/skins/coramy_trade/InvoiceLine_priceView.form create mode 100755 product/Coramy/skins/coramy_trade/InvoiceLine_quantityView.form create mode 100755 product/Coramy/skins/coramy_trade/InvoiceLine_view.form create mode 100755 product/Coramy/skins/coramy_trade/PackingList_getDistinctContainerList.py create mode 100755 product/Coramy/skins/coramy_trade/PlanTransportExtand.py create mode 100755 product/Coramy/skins/coramy_trade/SaleInvoice_updateTransaction.py create mode 100755 product/Coramy/skins/coramy_trade/SalesPackingList_printForm.form create mode 100755 product/Coramy/skins/coramy_trade/sales_packing_list_container_list_print.pt diff --git a/product/Coramy/skins/coramy_mrp/PortalSimulation_fixDeliveryRule.py b/product/Coramy/skins/coramy_mrp/PortalSimulation_fixDeliveryRule.py new file mode 100755 index 0000000000..dd061c0e25 --- /dev/null +++ b/product/Coramy/skins/coramy_mrp/PortalSimulation_fixDeliveryRule.py @@ -0,0 +1,37 @@ +## Script (Python) "PortalSimulation_fixDeliveryRule" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +delivery_id = {} +delivery_list = [] + +for m in context.objectValues(): + id = '_'.join(m.getId().split('_')[0:4]) + if m.getDelivery() is not None: + delivery = m.getDeliveryValue() + delivery_id[id] = m.getDelivery() + else: + delivery_list.append(m) + m.setOrder(delivery_id[id]) + print "%s %s %s" % (id, m.getRelativeUrl(), delivery_id[id]) + + +# Build deliveries +movement_group = context.portal_simulation.collectMovement(delivery_list) +delivery_list = context.portal_simulation.buildDeliveryList(movement_group) + +# Change workflow state +for new_delivery in delivery_list : + # Copy local roles + for k, v in delivery.get_local_roles(): + new_delivery.manage_addLocalRoles(k,v) + # update the state of the created deliveries to 'confirmed' + #new_delivery.confirm() + print "Created delivery %s" % new_delivery.getId() + +return printed diff --git a/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py b/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py new file mode 100755 index 0000000000..778e7288c0 --- /dev/null +++ b/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py @@ -0,0 +1,33 @@ +## Script (Python) "PortalSimulation_updateAssetPrice" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##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: + print ' '.join(map(lambda x:str(x), i)) + +return printed diff --git a/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py b/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py new file mode 100755 index 0000000000..27ed12f097 --- /dev/null +++ b/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py @@ -0,0 +1,51 @@ +## Script (Python) "ZeroStock_buildOrderList" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +if 1: + # 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()) + + # Empty Zero Stock + context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds()) + + # 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() + +# Collect movements in Zero Stock applied rule +zs_movement_list = context.portal_simulation.zero_stock.contentValues() + +# keep only movements with a Modele resource +movement_list = [] +for movement in zs_movement_list[0:100] : + 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 +root_group = context.portal_simulation.collectMovement(movement_list) +order_list = context.portal_simulation.buildOrderList(root_group) + +# update produced orders +for order in order_list: + order.autoPlan() + order.purchase_order_apply_condition() + +# 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()) + +request = context.REQUEST +redirect_url = '%s/view?%s' % ( context.absolute_url() + , 'portal_status_message=%s+propositions+OF+créés.' % len(order_list) + ) + +request[ 'RESPONSE' ].redirect( redirect_url ) diff --git a/product/Coramy/skins/coramy_pdm/tissu_list_export.py b/product/Coramy/skins/coramy_pdm/tissu_list_export.py new file mode 100755 index 0000000000..3180ddeb42 --- /dev/null +++ b/product/Coramy/skins/coramy_pdm/tissu_list_export.py @@ -0,0 +1,31 @@ +## Script (Python) "tissu_list_export" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +selection = context.portal_selections.getSelectionFor('tissu_selection',REQUEST=context.REQUEST) +tissu_list = selection(context=context) +request = context.REQUEST +tab = '\t' +cr = '\n' + +export ="Référence"+tab+"Fournisseur"+tab+"Réf. Fournisseur"+tab+"Collection"+tab+"Description"+cr +for tissu_item in tissu_list: + tissu=tissu_item.getObject() + if tissu <> None : + ligne_tissu = '' + ligne_tissu += str(tissu.getId())+tab + ligne_tissu += str(tissu.getDefaultSourceTitle())+tab + ligne_tissu += str(tissu.getSourceReference())+tab + ligne_tissu += str(tissu.getCollection())+tab + ligne_tissu += str(tissu.getDescription())+tab + + export += ligne_tissu+cr + +request.RESPONSE.setHeader('Content-Type','application/text') + +return export diff --git a/product/Coramy/skins/coramy_trade/ContainerLine_zGetTotal.zsql b/product/Coramy/skins/coramy_trade/ContainerLine_zGetTotal.zsql new file mode 100755 index 0000000000..6df107da08 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/ContainerLine_zGetTotal.zsql @@ -0,0 +1,21 @@ +<dtml-comment> +title: +connection_id:MySQL +max_rows:1000 +max_cache:100 +cache_time:0 +class_name: +class_file: +</dtml-comment> +<params>uid</params> +SELECT + SUM(quantity) AS total_quantity, + SUM(total_price) AS total_price, + SUM(target_quantity) AS target_total_quantity, + SUM(target_total_price) AS target_total_price, + AVG(price) AS average_price +FROM catalog, movement +WHERE + catalog.parent_uid = <dtml-sqlvar uid type="int"> +AND + catalog.uid = movement.uid diff --git a/product/Coramy/skins/coramy_trade/Container_oneClicInput.py b/product/Coramy/skins/coramy_trade/Container_oneClicInput.py new file mode 100755 index 0000000000..3e2f11cb78 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Container_oneClicInput.py @@ -0,0 +1,121 @@ +## Script (Python) "Container_oneClicInput" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters=form_id='',selection_index=None,selection_name='',dialog_category='object_exchange',container_type='',gross_weight=0,listbox=None,cancel_url='',next_container_int_index=1 +##title= +## +# first we build a dict of desired container lines +# key of dict : id of resource +# item of dict : tuples (resource_value, variation_category_list, quantity) +delivery = context +next_container_number = next_container_int_index + +#desired_lines = {} +desired_containers = {} +for relative_url, listitem in listbox.items() : + container_index = listitem['container_index'] + if not container_index in desired_containers.keys() : + desired_containers[container_index] = {} + other_quantity = listitem['container_quantity'] + listitem_value = context.restrictedTraverse(relative_url) + if listitem_value is not None : + if other_quantity : + container_quantity = other_quantity + else : + container_quantity = listitem_value.getQuantity() + my_resource = listitem_value.getResourceValue() + if my_resource is not None : + if my_resource.getRelativeUrl() in desired_containers[container_index].keys() : + desired_containers[container_index][my_resource.getRelativeUrl()].append((listitem_value.getVariationCategoryList(), container_quantity)) + else : + desired_containers[container_index][my_resource.getRelativeUrl()] = [(listitem_value.getVariationCategoryList(), container_quantity)] + +# we build as many containers as needed +container_key_list = desired_containers.keys() +container_key_list.sort() +for key in container_key_list : + desired_lines = desired_containers[key] + new_container_id = 'c'+str(next_container_number) + # we use container_type to know which are the resource (and variation) of the container + container_type_item_list = container_type.split('/') + container_resource_url = '/'.join(container_type_item_list[0:2]) + cointainer_resource_variation = 'variante/'+container_type + context.portal_types.constructContent(type_name = 'Container', + container = delivery, + int_index = next_container_number, + serial_number = "%06d%04d" % (int(delivery.getId()),next_container_number), + resource = container_resource_url, + variation_base_category_list = ['variante'], + variation_category_list = [cointainer_resource_variation], + gross_weight = gross_weight, + id = new_container_id, + ) + next_container_number += 1 + container = delivery[new_container_id] + container.flushActivity(invoke=1) + + # print container label + container.Container_printLabel() + + # now build container_lines + for key in desired_lines.keys() : + new_container_line_id = str(container.generateNewId()) + + # compute variation_base_category_list and variation_category_list for this line + line_variation_base_category_dict = {} + line_variation_category_list = [] + + for my_tuple in desired_lines[key] : + + for variation_item in my_tuple[0] : + if not variation_item in line_variation_category_list : + line_variation_category_list.append(variation_item) + variation_base_category_items = variation_item.split('/') + if len(variation_base_category_items) > 0 : + line_variation_base_category_dict[variation_base_category_items[0]] = 1 + + line_variation_base_category_list = line_variation_base_category_dict.keys() + + # construct new content (container_line) + my_resource_url = key + context.portal_types.constructContent(type_name = 'Container Line', + container = container, + id = new_container_line_id, + resource = my_resource_url, + variation_base_category_list = line_variation_base_category_list, + variation_category_list = line_variation_category_list + ) + container_line = container[new_container_line_id] + + # set target_quantities in container_lines + container_cell_list = container_line.contentValues() + for my_tuple in desired_lines[key] : + quantity_updated = 0 + for container_cell in container_cell_list : + if container_cell.test(context.asContext(categories=my_tuple[0])) : + container_cell.setTargetQuantity(my_tuple[1]) + container_cell.flushActivity(invoke=1) + quantity_updated = 1 + break + # if no cell according to variation_category_list was found + # or no variation at all, we update the container_line + if not quantity_updated : + container_line.setTargetQuantity(my_tuple[1]) + container_line.flushActivity(invoke=1) + + # update target_quantities on delivery_lines or cells + container.edit() + +redirect_url = '%s/%s?selection_name=%s&dialog_category=%s&form_id=%s&cancel_url=%s&%s' % ( context.absolute_url() + , 'Container_fastInputForm' + , selection_name + , dialog_category + , form_id + , cancel_url + , 'portal_status_message=%s+colis+créé(s)' % len(container_key_list) + ) + +context.REQUEST[ 'RESPONSE' ].redirect( redirect_url ) diff --git a/product/Coramy/skins/coramy_trade/Container_oneClicInputForm.form b/product/Coramy/skins/coramy_trade/Container_oneClicInputForm.form new file mode 100755 index 0000000000..9db969fee4 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Container_oneClicInputForm.form @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="iso-8859-1"?> + +<form> + <title>Saisie immédiate</title> + <name>Container_oneClicInputForm</name> + <action>Container_oneClicInput</action> + <enctype>multipart/form-data</enctype> + <method>POST</method> + <pt>form_dialog</pt> + + <groups> + <group> + <title>left</title> + <fields> + + <field><id>my_container_type</id> <type>ListField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <first_item type="int">0</first_item> + <hidden type="int">0</hidden> + <items type="list">[('carton A', 'composant/CAame/A'), ('carton B', 'composant/CAame/B'), ('carton C', 'composant/CAame/C'), ('carton D1', 'composant/CAame/D1'), ('carton D2', 'composant/CAame/D2'), ('carton D3', 'composant/CAame/D3')]</items> + <required type="int">1</required> + <size type="int">1</size> + <title>Type de colis</title> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + <field><id>my_gross_weight</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default>0.0</default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">1</required> + <title>Poids brut (kg)</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>right</title> + <fields> + + <field><id>my_next_container_int_index</id> <type>IntegerField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default>1</default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <end></end> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">1</required> + <start></start> + <title>Prochain numéro</title> + </values> + <tales> + <default>python:len(here.contentValues(filter={'portal_type':'Container'}))+1</default> + </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="not_integer">You did not enter an integer.</message> + <message name="integer_out_of_range">The integer you entered was out of range.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>center</title> + <fields> + + </fields> + </group> + <group> + <title>bottom</title> + <fields> + + <field><id>listbox</id> <type>ListBox</type> + <values> + <all_columns type="list">[]</all_columns> + <all_editable_columns type="list">[]</all_editable_columns> + <alternate_name></alternate_name> + <columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('Amount_getTailleClient', 'Taille client'), ('quantity', 'Quantit\xe9e demand\xe9e'), ('DeliveryCell_getContainedTargetQuantity', 'Quantit\xe9e colis\xe9e'), ('container_quantity', 'Autre quantit\xe9'), ('container_index', 'Ordre colis'), ('quantity_unit', 'Unit\xe9')]</columns> + <css_class></css_class> + <default></default> + <default_params type="list">[]</default_params> + <description></description> + <domain_root_list type="list">[]</domain_root_list> + <domain_tree type="int">0</domain_tree> + <editable_columns type="list">[('container_quantity', 'container_quantity'), ('container_index', 'container_index')]</editable_columns> + <external_validator></external_validator> + <global_attributes type="list">[]</global_attributes> + <hidden type="int">0</hidden> + <lines type="int">100</lines> + <list_action>folder_contents</list_action> + <list_method type="method">Delivery_zGetNeededCellList</list_method> + <meta_types type="list">[]</meta_types> + <portal_types type="list">[]</portal_types> + <report_root_list type="list">[]</report_root_list> + <report_tree type="int">0</report_tree> + <search type="int">0</search> + <search_columns type="list">[]</search_columns> + <select type="int">0</select> + <selection_name>delivery_cells_selection</selection_name> + <sort type="list">[('variation_text', 'variation_text')]</sort> + <stat_method></stat_method> + <title>Contenu du colis</title> + </values> + <tales> + </tales> + <messages> + <message name="external_validator_failed">The input failed the external validator.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>hidden</title> + <fields> + + <field><id>listbox_container_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>Autre quantité</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>listbox_container_index</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default>1</default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">5</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>Ordre colis</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + </fields> + </group> + </groups> +</form> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py b/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py new file mode 100755 index 0000000000..c1031316f4 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py @@ -0,0 +1,167 @@ +## Script (Python) "Container_printExtandLabel" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +from Products.Coramy.MetoAPI import selectMeter, startFormat, setDecoration, setPrintSpeed, setPaperSpeed, setPixel, setTemparature, setNumber, endFormat, printText, printLine, printFrame, setAsdFont + + +def chaine(num, div): + case = { + 10 : 1, + 100 : 2, + 1000: 3, + 10000: 4, + 100000: 5, + 1000000: 6 + + } + longueur = case[div] + #longueur = div / 10 + tmp = str( int(num) % div) + + result = '' + for i in range(0,longueur): + result += '0' + + result = result[:-len(tmp)] + tmp + return result + + + +raw_string = '' +container = context + + +# selecting printer (user dependent) +local_user = container.portal_membership.getAuthenticatedMember().getUserName() +if local_user == 'Nicole_Denis' : + printer_name = 'Meto_XS40_2' +elif local_user == 'Christelle_Megret' : + printer_name = 'Meto_XS40_3' +elif local_user == 'Jocelyne_Olejarz' : + printer_name = 'Meto_XS40_4' +elif local_user == 'Nathalie_Wadoux' : + printer_name = 'Meto_XS40_5' +else : + printer_name = 'Meto_XS40_2' + +delivery = container.aq_parent + +# Destination +client_title = delivery.getDestinationValue(portal_type=['Organisation']).getTitle() +client_address_items = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultAddress().asText(country='France').split('\n') +client_address_1 = client_address_items[0] +if len(client_address_items) > 2 : + client_address_2 = client_address_items[1] +else : + client_address_2 = '' +client_city = client_address_items[len(client_address_items)-1] +client_zip_code = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultAddress().getZipCode() + +# Expediteur +source_section = delivery.getSourceSectionTitle() +list = delivery.portal_catalog(Title=source_section, portal_type = 'Organisation') +if len(list) > 0: + expe = list[0].getObject() + + expe_title = expe.getTitle() + expe_address_items = expe.getDefaultAddress().asText(country='France').split('\n') + expe_address = expe_address_items[0] + expe_city = expe_address_items[len(expe_address_items)-1] + + +# Printing protocol starts here +# first set some parameters +raw_string += selectMeter() +raw_string += setAsdFont() +#raw_string += setDecoration(1) +raw_string += startFormat() +raw_string += setPrintSpeed() +raw_string += setPaperSpeed() +raw_string += setTemparature() + + +# then design the label +# adress +raw_string += printFrame(1, 29, 41, 35, 99, 5, 5, 10) +# ref colis +raw_string += printFrame(1, 29, 8, 35, 33, 5, 5, 10) +# code produit extand +raw_string += printFrame(1, 3, 94, 26, 46, 5, 5, 10) +raw_string += printLine(1, 3, 64, 15, 30, 10) +# dpt +raw_string += printFrame(1, 18, 64, 11, 30, 5, 5, 10) +# expediteur +raw_string += printFrame(1, 3, 8, 26, 56, 5, 5, 10) + + +# calcul modulo +#recepisse = str(int(atof(delivery.getId())) % 1000000) + str( container.getIntIndex() % 100 ) +recepisse = chaine( delivery.getId() , 1000000) + chaine( container.getIntIndex() , 100 ) + + +case_society = { + 'BLS':'5433', + 'Houvenaegel':'1194', + 'Coramy':'0193' +} +code_client = case_society[ source_section ] + +code = '12119591'+code_client+'4012'+recepisse + chaine( container.getGrossWeight() * 10 , 1000 ) + '00' + client_zip_code[:2] +totpair = int(code[0]) +totimpair = 0 + +for i in range(15): + totimpair += int(code[(2*i)+1]) + totpair += int(code[(2*i)+2]) + +cal1 = str((totpair * 3) + totimpair) +digit = str ( 10 - int( cal1[ len(cal1) - 1 ] ) ) + +if digit == '10': + digit = '0' + +code_barre = code+digit + + + +# code barre +raw_string += printText(2, "d", 0, 0, 300, 70, 139, code_barre, 10) +raw_string += printText(2, "9", 0, 0, 300, 65, 111, code_barre, 10) + + +# expediteur +raw_string += printText(2, "9", 0, 0, 2, 22, 62, "Expediteur", 10) +raw_string += printText(2, "9", 0, 0, 2, 15, 62, expe_title , 10) +raw_string += printText(2, "9", 0, 0, 1, 10, 62, expe_address , 10) +raw_string += printText(2, "9", 0, 0, 1, 4, 62, expe_city , 10) + +# destinataire +raw_string += printText(2, "9", 0, 0, 2, 56, 139, client_title , 10) +raw_string += printText(2, "9", 0, 0, 2, 46, 139, client_address_1 , 10) +raw_string += printText(2, "9", 0, 0, 2, 41, 139, client_address_2 , 10) +raw_string += printText(2, "9", 0, 0, 3, 31, 139, client_city , 10) + +# colis +raw_string += printText(2, "9", 0, 0, 1, 58, 38, "Cde "+ delivery.getId() , 10) +raw_string += printText(2, "9", 0, 0, 1, 41, 38, "Poids "+ str( container.getGrossWeight()) + " Kg", 10) +raw_string += printText(2, "9", 0, 0, 1, 49, 38, "Colis "+ str(container.getIntIndex()), 10) +raw_string += printText(2, "9", 0, 0, 1, 32, 38, "Ref. "+ recepisse, 10) +raw_string += printText(2, "9", 0, 0, 4, 18, 134, "EXTAND", 10) +raw_string += printText(2, "9", 0, 0, 6, 3, 130, "B12", 10) +raw_string += printText(2, "9", 0, 0, 5, 17, 86, client_zip_code[:2] , 10) + +raw_string += printText(2, "9", 0, 0, 6, 2, 87, context.PlanTransportExtand(client_zip_code[:2])[1] , 10) + +# set the quentity to print +raw_string += setNumber() +raw_string += endFormat() + +# send data to printer +#return chaine(94.2,10000) +context.sendRawToCups(printer_name, raw_string) diff --git a/product/Coramy/skins/coramy_trade/Container_printLabel.py b/product/Coramy/skins/coramy_trade/Container_printLabel.py new file mode 100755 index 0000000000..dd463cd9eb --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Container_printLabel.py @@ -0,0 +1,16 @@ +## Script (Python) "Container_printLabel" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +# print container label +container = context + +if container.aq_parent.getDeliveryMode() == 'Transporteur/Extand' : + container.Container_printExtandLabel() +else : + container.Container_printMetoLabel() diff --git a/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py b/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py new file mode 100755 index 0000000000..5e87bd7e8b --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py @@ -0,0 +1,93 @@ +## Script (Python) "Container_sendExtandEdi" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +from DateTime import DateTime +from string import zfill,ljust + +request = context.REQUEST +msg = '' + + +def decoupe(s,width): + from string import ljust + import string + if len(s) > width: + result = s[-width:] + else: + #result = string.ljust(s,width) + result = (' ' * (width-len(s))) + s + #return ' '+s + return result + +def chaine(num, width): + s = str(int(num)) + if len(s) > width: + result = s[-width:] + else: + result = zfill(s,width) + return result + + +object_list = context.object_action_list(selection_name='sales_packing_list_selection') +for delivery in object_list: + + if delivery.getDeliveryMode() == 'Transporteur/Extand': + + # Destination + client_title = delivery.getDestinationValue(portal_type=['Organisation']).getTitle() + client_address_items = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultAddress().asText(country='France').split('\n') + client_address_1 = client_address_items[0] + if len(client_address_items) > 2 : + client_address_2 = client_address_items[1] + else : + client_address_2 = '' + if len(client_address_items) > 3 : + client_address_3 = client_address_items[2] + else : + client_address_3 = '' + + #client_city = client_address_items[len(client_address_items)-1] + client_city = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultAddress().getCity() + + client_zip_code = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultAddress().getZipCode() + + client_tel = delivery.getDestinationValue(portal_type=['Organisation']).getDefaultTelephone().asText().split('\n')[0] + + + + + plat = context.PlanTransportExtand(client_zip_code[:2])[0] + + + container_list = delivery.contentValues(filter={'portal_type':'Container'}) + for container in container_list: + + #recepisse = "%08d%02d" % (delivery.getId() ,container.getIntIndex()) + recepisse = chaine( delivery.getId(), 8 )+chaine(str(container.getIntIndex()) , 2) + + case_society = { + 'BLS':'5433', + 'Houvenaegel':'1194', + 'Coramy':'0193' + } + source_section = delivery.getSourceSectionTitle() + code_client = case_society[ source_section ] + + msg += "301959"+code_client+recepisse+"0100"+client_zip_code[:2]+chaine(container.getGrossWeight() * 10 , 3) + + msg += DateTime().strftime("%Y%m%d") + + num_com_client = delivery.getCausalityValue(portal_type=['Sales Order']).getDestinationReference() + msg += plat+"001000"+decoupe( num_com_client ,80)+decoupe(client_title ,32)+decoupe(client_address_1,32) + msg += decoupe(client_address_2,32)+decoupe(client_address_3,32)+decoupe(client_zip_code,10) + msg += decoupe(client_city,32)+decoupe(client_tel,16)+'\r\n' + + +request.RESPONSE.setHeader('Content-Type','application/text') +return msg diff --git a/product/Coramy/skins/coramy_trade/Delivery_zGetNeededCellList.zsql b/product/Coramy/skins/coramy_trade/Delivery_zGetNeededCellList.zsql new file mode 100755 index 0000000000..9e589f6a9f --- /dev/null +++ b/product/Coramy/skins/coramy_trade/Delivery_zGetNeededCellList.zsql @@ -0,0 +1,30 @@ +<dtml-comment> +title: +connection_id:MySQL +max_rows:1000 +max_cache:100 +cache_time:0 +class_name:ZSQLBrain +class_file:zsqlbrain.py +</dtml-comment> +<params>uid +sort_on</params> +SELECT + cell.uid, cell.Id, cell.path, cell.Description, movement.variation_text +FROM + catalog as cell, movement +WHERE + movement.delivery_uid = <dtml-sqlvar uid type="int"> +AND + movement.uid = cell.uid +AND + movement.is_accountable = 1 +AND + movement.quantity <> 0 +AND + cell.portal_type <> "Simulation Movement" +AND + cell.portal_type <> "Container" +<dtml-if sort_on>ORDER BY + <dtml-var sort_on> +</dtml-if> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/InvoiceLine_priceView.form b/product/Coramy/skins/coramy_trade/InvoiceLine_priceView.form new file mode 100755 index 0000000000..3b0ff782a8 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/InvoiceLine_priceView.form @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="iso-8859-1"?> + +<form> + <title>Ligne de livraison</title> + <name>packing_list_line_quantity_view</name> + <action>base_edit</action> + <enctype>multipart/form-data</enctype> + <method>POST</method> + <pt>form_view</pt> + + <groups> + <group> + <title>Default</title> + <fields> + + <field><id>my_id</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">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <max_length></max_length> + <required type="int">1</required> + <title>Ligne n°</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> + </fields> + </group> + <group> + <title>right</title> + <fields> + + </fields> + </group> + <group> + <title>center</title> + <fields> + + </fields> + </group> + <group> + <title>bottom</title> + <fields> + + <field><id>matrixbox</id> <type>MatrixBox</type> + <values> + <all_editable_attributes type="list">[('ttarget_quantity', 'target_quantity'), ('quantity', 'quantity'), ('price', 'price'), ('predicate_value', 'predicate_value'), ('variation_category_list', 'variation_category_list')]</all_editable_attributes> + <alternate_name></alternate_name> + <cell_base_id>movement</cell_base_id> + <cell_range type="list">[]</cell_range> + <columns type="list">[('None', 'None')]</columns> + <css_class></css_class> + <default></default> + <description></description> + <editable_attributes type="list">[('target_quantity', 'target_quantity'), ('quantity', 'quantity'), ('price', 'price'), ('predicate_value', 'predicate_value'), ('variation_category_list', 'variation_category_list')]</editable_attributes> + <external_validator></external_validator> + <getter_method></getter_method> + <global_attributes type="list">[('domain_base_category_list', 'domain_base_category_list'), ('mapped_value_property_list', 'mapped_value_property_list'), ('predicate_operator', 'predicate_operator')]</global_attributes> + <hidden type="int">0</hidden> + <lines type="list">[('None', 'None')]</lines> + <setter_method></setter_method> + <tabs type="list">[('None', 'None')]</tabs> + <title>matrixbox</title> + <update_cell_range type="int">1</update_cell_range> + </values> + <tales> + <columns>python:here.order_line_matrix_item_list(base_category_list = ('taille',), base=1)</columns> + <lines>python:here.order_line_matrix_item_list(base_category_list = ('coloris','variante'), base=1)</lines> + <tabs>python:here.order_line_matrix_item_list(base_category_list = ('taille','coloris','variante'), base=1, include=0)</tabs> + </tales> + <messages> + <message name="external_validator_failed">The input failed the external validator.</message> + </messages> + </field> + <field><id>domain_base_category_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>Valid Domain</title> + <width type="int">40</width> + </values> + <tales> + <default>here/getVariationBaseCategoryList</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>predicate_operator</id> <type>StringField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default>SUPERSET_OF</default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">20</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <max_length></max_length> + <required type="int">0</required> + <title>Operator</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>mapped_value_property_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">['target_quantity', 'quantity', 'price']</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>Modified categories</title> + <width type="int">40</width> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>hidden</title> + <fields> + + <field><id>matrixbox_predicate_value</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>matrixbox_predicate_value</title> + <width type="int">40</width> + </values> + <tales> + <default>python:cell_index</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>matrixbox_variation_category_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>matrixbox_predicate_value</title> + <width type="int">40</width> + </values> + <tales> + <default>python:cell_index</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>matrixbox_price</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>matrixbox_price</title> + </values> + <tales> + <default>python:cell.getProperty('price')</default> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>matrixbox_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <required type="int">0</required> + <title>matrixbox_quantity</title> + </values> + <tales> + <default>python:cell.getProperty('quantity')</default> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>matrixbox_target_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <required type="int">0</required> + <title>matrixbox_target_quantity</title> + </values> + <tales> + <default>python:cell.getProperty('target_quantity')</default> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + </fields> + </group> + </groups> +</form> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/InvoiceLine_quantityView.form b/product/Coramy/skins/coramy_trade/InvoiceLine_quantityView.form new file mode 100755 index 0000000000..8b911fd2fa --- /dev/null +++ b/product/Coramy/skins/coramy_trade/InvoiceLine_quantityView.form @@ -0,0 +1,278 @@ +<?xml version="1.0" encoding="iso-8859-1"?> + +<form> + <title>Ligne de livraison</title> + <name>packing_list_line_quantity_view</name> + <action>base_edit</action> + <enctype>multipart/form-data</enctype> + <method>POST</method> + <pt>form_view</pt> + + <groups> + <group> + <title>Default</title> + <fields> + + <field><id>my_id</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">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <max_length></max_length> + <required type="int">1</required> + <title>Ligne n°</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> + </fields> + </group> + <group> + <title>right</title> + <fields> + + </fields> + </group> + <group> + <title>center</title> + <fields> + + </fields> + </group> + <group> + <title>bottom</title> + <fields> + + <field><id>matrixbox</id> <type>MatrixBox</type> + <values> + <all_editable_attributes type="list">[('quantity', 'quantity'), ('price', 'price'), ('predicate_value', 'predicate_value'), ('variation_category_list', 'variation_category_list')]</all_editable_attributes> + <alternate_name></alternate_name> + <cell_base_id>movement</cell_base_id> + <cell_range type="list">[]</cell_range> + <columns type="list">[('None', 'None')]</columns> + <css_class></css_class> + <default></default> + <description></description> + <editable_attributes type="list">[('quantity', 'quantity'), ('price', 'price'), ('predicate_value', 'predicate_value'), ('variation_category_list', 'variation_category_list')]</editable_attributes> + <external_validator></external_validator> + <getter_method></getter_method> + <global_attributes type="list">[('domain_base_category_list', 'domain_base_category_list'), ('mapped_value_property_list', 'mapped_value_property_list'), ('predicate_operator', 'predicate_operator')]</global_attributes> + <hidden type="int">0</hidden> + <lines type="list">[('None', 'None')]</lines> + <setter_method></setter_method> + <tabs type="list">[('None', 'None')]</tabs> + <title>matrixbox</title> + <update_cell_range type="int">1</update_cell_range> + </values> + <tales> + <columns>python:here.order_line_matrix_item_list(base_category_list = ('taille',), base=1)</columns> + <lines>python:here.order_line_matrix_item_list(base_category_list = ('coloris','variante'), base=1)</lines> + <tabs>python:here.order_line_matrix_item_list(base_category_list = ('taille','coloris','variante'), base=1, include=0)</tabs> + </tales> + <messages> + <message name="external_validator_failed">The input failed the external validator.</message> + </messages> + </field> + <field><id>domain_base_category_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>Valid Domain</title> + <width type="int">40</width> + </values> + <tales> + <default>here/getVariationBaseCategoryList</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>predicate_operator</id> <type>StringField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default>SUPERSET_OF</default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">20</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <max_length></max_length> + <required type="int">0</required> + <title>Operator</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>mapped_value_property_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">['target_quantity', 'quantity', 'price']</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>Modified categories</title> + <width type="int">40</width> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>hidden</title> + <fields> + + <field><id>matrixbox_predicate_value</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>matrixbox_predicate_value</title> + <width type="int">40</width> + </values> + <tales> + <default>python:cell_index</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>matrixbox_variation_category_list</id> <type>LinesField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">5</height> + <hidden type="int">1</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>matrixbox_predicate_value</title> + <width type="int">40</width> + </values> + <tales> + <default>python:cell_index</default> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>matrixbox_price</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <required type="int">0</required> + <title>matrixbox_price</title> + </values> + <tales> + <default>python:cell.getProperty('price')</default> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>matrixbox_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>matrixbox_quantity</title> + </values> + <tales> + <default>python:cell.getProperty('quantity')</default> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + </fields> + </group> + </groups> +</form> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/InvoiceLine_view.form b/product/Coramy/skins/coramy_trade/InvoiceLine_view.form new file mode 100755 index 0000000000..8e5d735898 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/InvoiceLine_view.form @@ -0,0 +1,331 @@ +<?xml version="1.0" encoding="iso-8859-1"?> + +<form> + <title>Ligne de livraison</title> + <name>sales_packing_list_line_view</name> + <action>base_edit</action> + <enctype>multipart/form-data</enctype> + <method>POST</method> + <pt>form_view</pt> + + <groups> + <group> + <title>left</title> + <fields> + + <field><id>my_id</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">5</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <max_length></max_length> + <required type="int">1</required> + <title>Ligne n°</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_description</id> <type>TextAreaField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <height type="int">2</height> + <hidden type="int">0</hidden> + <max_length></max_length> + <max_linelength></max_linelength> + <max_lines></max_lines> + <required type="int">0</required> + <title>Description</title> + <width type="int">40</width> + </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_many_lines">You entered too many lines.</message> + <message name="line_too_long">A line was too long.</message> + <message name="too_long">You entered too many characters.</message> + </messages> + </field> + <field><id>my_resource_relative_url</id> <type>RelationStringField</type> + <values> + <alternate_name></alternate_name> + <base_category>resource</base_category> + <catalog_index>relative_url</catalog_index> + <css_class></css_class> + <default></default> + <default_module>modele</default_module> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">40</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <jump_method>base_jump_relation</jump_method> + <max_length></max_length> + <portal_type type="list">[('Composant', 'Composant'), ('Tissu', 'Tissu'), ('Modele', 'Modele'), ('Forme', 'Forme'), ('Vetement', 'Vetement'), ('Category', 'Category'), ('Gamme', 'Gamme')]</portal_type> + <required type="int">0</required> + <title>Produit</title> + <truncate type="int">0</truncate> + <update_method>base_update_relation</update_method> + </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_variation_base_category_list</id> <type>MultiListField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <items type="list">[]</items> + <required type="int">0</required> + <size type="int">3</size> + <title>Axes variation</title> + </values> + <tales> + <items>here/getVariationRangeBaseCategoryList</items> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + <field><id>my_variation_category_list</id> <type>MultiListField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default type="list">[]</default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <items type="list">[]</items> + <required type="int">0</required> + <size type="int">8</size> + <title>Variantes</title> + </values> + <tales> + <items>here/getVariationRangeCategoryItemList</items> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + <field><id>my_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>Quantité par défaut</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>right</title> + <fields> + + <field><id>my_quantity_unit</id> <type>ListField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <first_item type="int">0</first_item> + <hidden type="int">0</hidden> + <items type="list">[]</items> + <required type="int">0</required> + <size type="int">1</size> + <title>Unité</title> + </values> + <tales> + <items>here/getQuantityUnitRangeItemList</items> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + <field><id>my_price</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">0</hidden> + <required type="int">0</required> + <title>Prix par défaut</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>spacer</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">1</hidden> + <max_length></max_length> + <required type="int">0</required> + <title> </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_total_quantity</id> <type>FloatField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <display_maxwidth></display_maxwidth> + <display_width type="int">10</display_width> + <external_validator></external_validator> + <extra></extra> + <hidden type="int">1</hidden> + <required type="int">0</required> + <title>Quantité facturée</title> + </values> + <tales> + <title>python:'Quantité facturée : %.2f' % here.getTotalQuantity()</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>my_value_added_tax_ratio</id> <type>FloatField</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> + <required type="int">0</required> + <title>Taux de TVA</title> + </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="not_float">You did not enter a floating point number.</message> + </messages> + </field> + <field><id>my_value_added_tax_recoverable</id> <type>ListField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <external_validator></external_validator> + <extra></extra> + <first_item type="int">0</first_item> + <hidden type="int">0</hidden> + <items type="list">[('Non', '0'), ('Oui', '1')]</items> + <required type="int">0</required> + <size type="int">1</size> + <title>Soumis à la TVA</title> + </values> + <tales> + <default>python:str(here.getValueAddedTaxRecoverable())</default> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + </fields> + </group> + <group> + <title>center</title> + <fields> + + </fields> + </group> + <group> + <title>bottom</title> + <fields> + + </fields> + </group> + <group> + <title>hidden</title> + <fields> + + </fields> + </group> + </groups> +</form> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/PackingList_getDistinctContainerList.py b/product/Coramy/skins/coramy_trade/PackingList_getDistinctContainerList.py new file mode 100755 index 0000000000..6307c8a530 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/PackingList_getDistinctContainerList.py @@ -0,0 +1,44 @@ +## Script (Python) "PackingList_getDistinctContainerList" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +# this method return a list of distinct containers +# it returns a sorted list of tuples (object container, range) +# the range is a tuple (first number of this container, last number of this container) + +delivery = context + +container_list = delivery.contentValues(filter={'portal_type' : 'Container'}) + +ordered_container_list = context.sort_object_list(unordered_list=container_list, sort_order = (('int_index', 'ASC'),) ) + +final_container_list = [] +if len(container_list) > 0 : + container_ref = container_list[0].getContainerText() + container_object = container_list[0] + first_container = 1 + last_container = 1 +else : + container_ref = '' + container_object = None + first_container = 0 + last_container = 0 + +for container in ordered_container_list : + if container.getContainerText() != container_ref : + # append tuple in final_container_list + final_container_list.append((container_object,(first_container,last_container))) + # reset variables + container_object = container + first_container = container.getIntIndex() + last_container = container.getIntIndex() + +# append final container in final_container_list +final_container_list.append((container_object,(first_container,last_container))) + +return final_container_list diff --git a/product/Coramy/skins/coramy_trade/PlanTransportExtand.py b/product/Coramy/skins/coramy_trade/PlanTransportExtand.py new file mode 100755 index 0000000000..3ac78722cc --- /dev/null +++ b/product/Coramy/skins/coramy_trade/PlanTransportExtand.py @@ -0,0 +1,111 @@ +## Script (Python) "PlanTransportExtand" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters=departement='' +##title= +## +plan_transport = { +'01':('901','01'), +'02':('951','51'), +'03':('963','63'), +'04':('984','84'), +'05':('938','38'), +'06':('906','06'), +'07':('926','26'), +'08':('951','51'), +'09':('932','32'), +'10':('910','10'), +'11':('932','32'), +'12':('982','82'), +'13':('913','13'), +'14':('914','14'), +'15':('963','63'), +'16':('916','16'), +'17':('979','79'), +'18':('945','45'), +'19':('987','87'), +'20':('920','20'), +'21':('921','21'), +'22':('935','35'), +'23':('987','87'), +'24':('987','87'), +'25':('925','25'), +'26':('926','26'), +'27':('976','76'), +'28':('978','78'), +'29':('929','29'), +'30':('984','84'), +'31':('931','31'), +'32':('932','32'), +'55':('954','54'), +'56':('956','56'), +'57':('957','57'), +'58':('921','21'), +'59':('959','59'), +'60':('960','60'), +'61':('972','72'), +'62':('962','62'), +'63':('963','63'), +'64':('964','64'), +'65':('964','64'), +'66':('966','66'), +'67':('967','67'), +'68':('968','68'), +'69':('969','69'), +'70':('925','25'), +'71':('921','21'), +'72':('972','72'), +'73':('974','74'), +'74':('974','74'), +'75':('975','75'), +'76':('976','76'), +'77':('977','77'), +'78':('978','78'), +'79':('979','79'), +'80':('960','60'), +'81':('982','82'), +'82':('982','82'), +'83':('983','83'), +'84':('984','84'), +'85':('944','44'), +'86':('937','37'), +'33':('933','33'), +'34':('934','34'), +'35':('935','35'), +'36':('937','37'), +'37':('937','37'), +'38':('938','38'), +'39':('921','21'), +'40':('964','64'), +'41':('945','45'), +'42':('942','42'), +'43':('942','42'), +'44':('944','44'), +'45':('945','45'), +'46':('982','82'), +'47':('933','33'), +'48':('966','66'), +'49':('949','49'), +'50':('914','14'), +'51':('951','51'), +'52':('910','10'), +'53':('972','72'), +'54':('954','54'), +'87':('987','87'), +'88':('954','54'), +'89':('910','10'), +'90':('925','25'), +'91':('994','94'), +'92':('995','95'), +'93':('992','92'), +'94':('994','94'), +'95':('995','95'), +'98':('906','06'), +} +if departement == '' : + return None +else : + return plan_transport[departement] diff --git a/product/Coramy/skins/coramy_trade/SaleInvoice_updateTransaction.py b/product/Coramy/skins/coramy_trade/SaleInvoice_updateTransaction.py new file mode 100755 index 0000000000..802f02ce88 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/SaleInvoice_updateTransaction.py @@ -0,0 +1,65 @@ +## Script (Python) "SaleInvoice_updateTransaction" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +# Create invoice lines +global total_price +global total_vat +global total_discount +total_price = 0.0 +total_vat = 0.0 +total_discount = 0.0 +invoice = context + +def updateTotal(l): + global total_price + global total_vat + global total_discount + if l.getPrice() in ('', None): + return 'Price is not defined for %s %s' % (l.getResource(), l.getVariationText()) + elif l.getQuantity(): + price = l.getPrice() * l.getQuantity() + total_price += price + if l.getValueAddedTaxRatio() and l.getValueAddedTaxRecoverable(): + total_vat += price * l.getValueAddedTaxRatio() + return None + +for l in context.contentValues(filter={'portal_type':"Invoice Line"}): + if l.hasCellContent(): + for c in l.contentValues(filter={'portal_type':"Invoice Cell"}): + error_message = updateTotal(c) + if error_message is not None: + return error_message + else: + error_message = updateTotal(l) + if error_message is not None: + return error_message + +# Generate accounting lines +# Income Line +if not invoice.hasObject('income'): + income = invoice.newContent(portal_type="Sale Invoice Transaction Line", id='income') +else: + income = context.income +income.edit(source='account/vente', destination='account/achat', + source_credit=total_price) +# Payable Line +if not invoice.hasObject('payable'): + payable = invoice.newContent(portal_type="Sale Invoice Transaction Line", id='payable') +else: + payable = context.payable +payable.edit(source='account/creance_client', destination='dette_fournisseur', + source_debit=total_price + total_vat) + +# VAT Line +if not invoice.hasObject('vat'): + vat = invoice.newContent(portal_type="Sale Invoice Transaction Line", id='vat') +else: + vat = context.vat +vat.edit(source='account/tva_collectee_196', destination='account/tva_recuperable_196', + source_credit=total_vat) diff --git a/product/Coramy/skins/coramy_trade/SalesPackingList_printForm.form b/product/Coramy/skins/coramy_trade/SalesPackingList_printForm.form new file mode 100755 index 0000000000..750cb3d581 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/SalesPackingList_printForm.form @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="iso-8859-1"?> + +<form> + <title>Imprimer</title> + <name>SalesPackingList_printForm</name> + <action>sales_packing_list_secure_print</action> + <enctype>multipart/form-data</enctype> + <method>POST</method> + <pt>form_dialog</pt> + + <groups> + <group> + <title>left</title> + <fields> + + <field><id>my_packing_list_page_template</id> <type>RadioField</type> + <values> + <alternate_name></alternate_name> + <css_class></css_class> + <default></default> + <description></description> + <external_validator></external_validator> + <first_item type="int">1</first_item> + <hidden type="int">0</hidden> + <items type="list">[('Bordereau de livraison', 'sales_packing_list_print'), ('Liste de colisage', 'sales_packing_list_container_list_print')]</items> + <orientation>vertical</orientation> + <required type="int">1</required> + <title>Impression demandée</title> + </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="unknown_selection">You selected an item that was not in the list.</message> + </messages> + </field> + </fields> + </group> + </groups> +</form> \ No newline at end of file diff --git a/product/Coramy/skins/coramy_trade/sales_packing_list_container_list_print.pt b/product/Coramy/skins/coramy_trade/sales_packing_list_container_list_print.pt new file mode 100755 index 0000000000..94df8e2255 --- /dev/null +++ b/product/Coramy/skins/coramy_trade/sales_packing_list_container_list_print.pt @@ -0,0 +1,210 @@ +<HTML> + <HEAD> + <meta http-equiv="content-type" content="text/html;charset=ISO-8859-1"> + <title tal:content="here/getTitle">Coramy</title> + <link rel=stylesheet type="text/css" href="modele_catalog_c"> + </HEAD> + <BODY bgcolor="#ffffff" tal:define="delivery_list python:here.object_action_list(selection_name='sales_packing_list_selection',max_nb=10); + page_number python:[0]"> + <TABLE tal:repeat="delivery delivery_list" width="660" height="955" cellpadding="0" cellspacing="0" tal:attributes="class python:here.PT_pageBreak(page_number)"> + <TABLE border="0" width="660" height="900" cellpadding="0" cellspacing="0" + tal:define="order python:delivery.getCausalityValue(portal_type=['Sales Order']); + destination python:delivery.getDestinationValue(portal_type=['Organisation']); + distinct_container_list python:delivery.PackingList_getDistinctContainerList(); + totalizer python:[0,0,0,0]"><!-- Tableau general --> + <TR> + <TD> + <TABLE border="0" width="100%" height="100%"> + <TR> + <TD class="Titre" tal:content="python:delivery.getSourceSectionTitle()">Coramy</TD> + <TD align="center"> + <span class="Titre2">Liste de colisage<span tal:content="python:' n° '+delivery.getId()"/></span><br> + Lieferschein Nr / Delivery note N° + </TD> + <TD align="right"> + <span tal:content="python:'Gravelines, le '+str(here.DateTime_getFormattedDate())"/> + </TD> + </TR> + </TABLE> + </TD> + </TR> + <TR height="18%"><!-- Infos --> + <TD><br> + <TABLE border="0" width="100%" height="100%"> + <TR> + <TD nowrap align="center" class="Bordereau">Commande N°<br>Auftrag Nr / Order N°<br><span class="Normal" tal:content="python:order.getDestinationReference()" /></TD> + <TD nowrap align="center" class="Bordereau" >Poids brut (Kg)<br>Brutto-gewicht / Gross weight <br><span class="Normal" tal:content="python:delivery.PackingList_getTotalGrossWeight()" /></TD> + <TD nowrap rowspan="3"> + <SPAN tal:condition="python:destination<>None"> + <b><SPAN tal:content="python:modules['string'].capwords(destination.getTitle())"/></b> + <br><SPAN tal:condition="python:destination.getPortalType()<>'Category'"> + <SPAN tal:define="address_items python:modules['string']. + split(destination.getDefaultAddress().asText(country='France'),'\n')"> + <SPAN tal:repeat="item address_items"> + <SPAN tal:content="item"/><br> + </SPAN> + </SPAN> + </SPAN> + </SPAN> + </TD> + <TD nowrap align="center" rowspan="2" class="Bordereau">Port<br>Porto / Freight<br><span class="Normal" tal:content="python:delivery.getIncoterm()" /></TD> + </TR> + <TR> + <TD nowrap align="center" class="Bordereau">Confirmation N°<br>Bestätigung Nr <br><span class="Normal" tal:content="python:order.getId()" /></TD> + <TD nowrap align="center" class="Bordereau">Nombre de colis<br>Kolli Anzahl / Nb of parcels <br><span class="Normal" tal:content="python:len(delivery.contentValues(filter={'portal_type':'Container'}))" /></TD> + </TR> + <TR> + <TD nowrap align="center" class="Bordereau"> Date d'expédition<br>Versand Tag / Sending Date <br><span class="Normal" tal:content="python:str(here.DateTime_getFormattedDate(delivery.getTargetStartDate()))" /></TD> + <TD nowrap align="center" class="Bordereau" >Nombre d'articles<br>Artikel Anzahl / Nb of items<br><span class="Normal" tal:content="python:delivery.getTargetTotalQuantity()" /></TD> + <TD nowrap align="center" class="Bordereau" >Transporteur <br> Carrier / Spediteur<br><span class="Normal" tal:content="python:delivery.getDeliveryMode()" /></TD> + </TR> + </TABLE> + </TD> + </TR> + + + <SPAN tal:repeat="container_template distinct_container_list"> + <SPAN tal:define="toto python:here.PT_reset_total_list(totalizer,[1])"/> + <SPAN tal:repeat="delivery_line python:container_template[0].contentValues(filter={'portal_type': + 'Container Line'})"> + <TR><!-- Matrice de ligne de livraison --> + <TD> + + <TABLE border="1" width="100%" + tal:define="correspondance_tailles python:delivery_line.getResourceValue().getSpecialiseValue(portal_type=['Correspondance Tailles']); + coloris_list python:delivery_line.Variated_getColorisList(); + taille_qty python:len(delivery_line.Variated_getTailleList(correspondance_tailles)[0]); + morphologie_list python:delivery_line.getMorphologieList() + "> + <TR> + <TD align="left" + tal:condition="python:container_template[1][0]==container_template[1][1]"> + <b tal:content="python:'Colis %s'%container_template[1][0]"/> + </TD> + <TD align="left" + tal:condition="python:container_template[1][0]<>container_template[1][1]"> + <b tal:content="python:'Colis %s à %s'%(container_template[1][0],container_template[1][1])"/> + </TD> + <TD tal:attributes="colspan python:taille_qty+1" align="center">Quantités réparties par tailles</TD> + </TR> + + <SPAN tal:condition="python:len(morphologie_list)==0" + tal:define="taille_list python:delivery_line.Variated_getTailleList(correspondance_tailles)"><!-- S'Il N'Y A PAS DE VARIANTES MORPHOLOGIQUES --> + <TR tal:condition="python:1"> + <TD nowrap><SPAN tal:content="python:'Modèle : %s' %delivery_line.getResourceValue().getId()"/></TD> + <TD rowspan="2" align="center" tal:repeat="index python:range(taille_qty)" + tal:content="python:taille_list[1][index]">36</TD><!-- BOUCLE SUR LE NB DE TAILLES --> + <TD align="center" rowspan="2" nowrap>Total</TD> + </TR> + <TR> + + <TD> + <SPAN tal:condition="python:delivery_line.getResourceValue().getPortalType()=='Modele'" width="30%" tal:content="python:delivery_line.getResourceValue().getComposition()"/> + <SPAN tal:condition="python:delivery_line.getResourceValue().getPortalType()=='Assortiment'" width="30%" tal:content="python:delivery_line.getResourceValue().getDescription()"/> + </TD> + </TR> + + <SPAN tal:condition="python:len(coloris_list[0])>0"> + <TR tal:repeat="index python:range(len(coloris_list[0]))"><!-- BOUCLE SUR LES COLORIS --> + <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,3])"/> + <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"/> + <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2,3],target_quantity)"/> + </SPAN> + <TD align="right" tal:content="python: '%.0f' %totalizer[3]"/> + </TR> + </SPAN> + + <SPAN tal:condition="python:len(coloris_list[0])==0"> + <TR><!-- PAS DE COLORIS --> + <TD align="left"></TD> + <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2,3])"/> + <SPAN 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,3],target_quantity)"/> + </SPAN> + <SPAN tal:condition="python:taille_qty==0" + tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2,3],delivery_line.getTargetQuantity())"/> + <TD align="right" tal:content="python: '%.0f' %totalizer[3]"/> + </TR> + </SPAN> + + <TR> + <TD align = "right" tal:attributes="colspan python:taille_qty+1">Total colis + </TD> + <TD align="right" tal:content="python: '%.0f' %totalizer[1]"> + </TD> + </TR> + </SPAN> + + <SPAN tal:condition="python:len(morphologie_list)>0"><!-- S'Il Y A DES VARIANTES MORPHOLOGIQUES --> + <SPAN tal:repeat="morphologie morphologie_list"> + <SPAN tal:define="taille_list python:delivery_line.Variated_getTailleList(correspondance_tailles,morphologie); + toto python:delivery_line.PT_reset_total_list(totalizer,[3])"><!-- BOUCLE SUR LES VARIANTES MORPHOLOGIQUES --> + <TR tal:condition="python:1"> + <TD nowrap><SPAN tal:content="python:'Modèle : %s' % '/'.join(morphologie.split('/')[1:])"/></TD> + <TD rowspan="2" align="center" tal:repeat="index python:range(taille_qty)" + tal:content="python:taille_list[1][index]">36</TD><!-- BOUCLE SUR LE NB DE TAILLES --> + <TD align="center" rowspan="2" nowrap>Total</TD> + </TR> + <TR> + + <TD> + <SPAN tal:condition="python:delivery_line.getResourceValue().getPortalType()=='Modele'" width="30%" tal:content="python:delivery_line.getResourceValue().getComposition()"/> + <SPAN tal:condition="python:delivery_line.getResourceValue().getPortalType()=='Assortiment'" width="30%" tal:content="python:delivery_line.getResourceValue().getDescription()"/> + </TD> + </TR> + + <TR tal:repeat="index python:range(len(coloris_list[0]))"><!-- BOUCLE SUR LES COLORIS --> + <TD align="left" tal:content="python:'coloris '+coloris_list[1][index]"></TD> + <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[3])"/> + <SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2],coloris_list[2][index],morphologie)"> + <TD align = right tal:content="python: '%.0f' %target_quantity"/> + <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2,3],target_quantity)"/> + </SPAN> + <TD align="right" tal:content="python: '%.0f' %totalizer[3]"/> + </TR> + </SPAN> + <TR> + <TD align = "right" tal:attributes="colspan python:taille_qty+1">Total colis + </TD> + <TD align="right" tal:content="python: '%.0f' %totalizer[1]"> + </TD> + </TR> + </SPAN> + + </SPAN> + + </TABLE> + </TD> + </TR> + + <TR tal:define="commentaires_list python:modules['string'].split('','\n')"><!-- Notes --> + <TD valign="top"> + <span tal:repeat="commentaires_item commentaires_list"> + <span tal:content="python:commentaires_item"/></span> + </TD> + </TR> + + </SPAN> + </SPAN> + + <TR> + <TD height="40%"/> + </TR> + <TR> + <TD tal:condition="python:delivery.getSourceSectionTitle()=='BLS'" align="center">BLS - 5 bis, rue Denis Cordonnier - 59820 Gravelines (FRANCE)<br>Tél. : + 33 (0) 3 28 51 86 26 - Fax : + 33 (0) 3 28 23 34 96 + <p class="Copy">S.A.R.L. au capital de 10.000 € - T.V.A. FR 51 442 959 243 - R.C. Dunkerque 442 959 243 - SIRET 442 959 243 00019</p> + </TD> + <TD tal:condition="python:delivery.getSourceSectionTitle()=='Houvenaegel'" align="center">Houvenaegel Création - 5 bis, rue Denis Cordonnier - 59820 Gravelines (FRANCE)<br>Tél. : + 33 (0) 3 28 51 91 55 - Fax : + 33 (0) 3 28 23 34 96 + <p class="Copy">S.A.R.L. au capital de 7.622,45 € - T.V.A. FR 07 422 769 810 - R.C. Dunkerque 422 769 810 - SIRET 422 769 810 00025</p> + </TD> + <TD tal:condition="python:delivery.getSourceSectionTitle()=='Coramy'" align="center">Coramy - 5 bis, rue Denis Cordonnier - 59820 Gravelines (FRANCE)<br>Tél. : + 33 (0) 3 28 51 91 51 - Fax : + 33 (0) 3 28 23 34 96 + <p class="Copy">S.A.S. au capital de 435.200 € - T.V.A. FR 67 611 750 274 - R.C. Dunkerque 611 750 274 - SIRET 611 750 274 00023 - CNUF 15971</p> + </TD> + </TR> + </TABLE> + </TABLE> + </BODY> +</HTML> -- 2.30.9