diff --git a/product/ERP5Shop/Document/ShopOrder.py b/product/ERP5Shop/Document/ShopOrder.py index 7214e804c62f500091cebef0c2c1d3c5cd951924..d6e6f7ecc2cdf5b2f3cebc4d87077cce76eac8b4 100755 --- a/product/ERP5Shop/Document/ShopOrder.py +++ b/product/ERP5Shop/Document/ShopOrder.py @@ -33,6 +33,8 @@ from Acquisition import aq_base from Products.CMFCore.utils import getToolByName from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface +from Products.ERP5Type.Base import Base +from Products.ERP5Type.XMLExportImport import Base_asXML from Products.ERP5.VariationValue import VariationValue from Products.ERP5.Document.Order import Order from Products.ERP5.Document.Delivery import Delivery @@ -45,10 +47,21 @@ from Products.MMMShop.utils import getUniqueID from Products.CMFCore.WorkflowCore import WorkflowMethod +from cStringIO import StringIO + +from xml.dom.ext import PrettyPrint +from xml.dom.ext.reader import PyExpat + +from email import Encoders +from email.MIMEBase import MIMEBase +import pickle + from zLOG import LOG + match_path = re.compile('http.*//[^/]*/(.*)') + class OrderLine(MMMOrderLine, ERP5OrderLine): """ An orderline describes 1 line of an order @@ -89,6 +102,86 @@ class OrderLine(MMMOrderLine, ERP5OrderLine): product = self.getProduct() return product.newVariationValue(context=self) + security.declareProtected(Permissions.AccessContentsInformation, 'asXML') + def asXML(self, ident=0): + """ + Generate an standard xml text corresponding to the content of an OrderLine and + add some special properties + """ + # Get the source XML + source_xml_str = Base_asXML(self, ident=ident) + # Create the PyExpat reader + reader = PyExpat.Reader() + # Create thr DOM tree from the xml string + source_xml = reader.fromString(source_xml_str) + # Get the XML root + xml_root = source_xml.documentElement + # Get the XML document + xml_doc = xml_root.parentNode + # Add product-related informations + product = self.getProduct() + LOG("PRODUCT >>>>>>>>>>",0,repr(product)) + self.addSimpleNode(xml_doc, xml_root + , "product_id", "string", product.getId()) + self.addSimpleNode(xml_doc, xml_root + , "product_title", "string", self.getProductTitle()) + self.addSimpleNode(xml_doc, xml_root + , "product_description", "string", product.getDescription()) + self.addSimpleNode(xml_doc, xml_root + , "product_processor_price", "object", self.toObjString(product.processor_price)) + self.addSimpleNode(xml_doc, xml_root + , "product_disk_price", "object", self.toObjString(product.disk_price)) + self.addSimpleNode(xml_doc, xml_root + , "product_memory_price", "object", self.toObjString(product.memory_price)) + self.addSimpleNode(xml_doc, xml_root + , "product_option_price", "object", self.toObjString(product.option_price)) + self.addSimpleNode(xml_doc, xml_root + , "product_price", "float", str(product.getPrice())) + self.addSimpleNode(xml_doc, xml_root + , "product_expiration_date", "date", str(product.getExpirationDate())) + self.addSimpleNode(xml_doc, xml_root + , "product_delivery_days", "int", str(product.getDeliveryDays())) + return self.dom2str(xml_root) + + security.declarePrivate('addSimpleNode') + def addSimpleNode(self, xml_doc=None, xml_root=None, name=None, type=None, content=None): + """ + This function add a simple Node in the XML description of the order line + """ + if name == None or xml_doc == None or xml_root == None: + return + new_child = xml_doc.createElement(name) + new_text = xml_doc.createTextNode(content) + new_child.appendChild(new_text) + if type != None: + new_child.setAttribute("type", type) + xml_root.appendChild(new_child) + + security.declarePrivate('toObjString') + def toObjString(self, object): + """ + Convert an object to a safe string for XML Export + """ + value = aq_base(object) + value = pickle.dumps(value) + msg = MIMEBase('application','octet-stream') + msg.set_payload(value) + Encoders.encode_base64(msg) + ascii_data = msg.get_payload() + ascii_data = ascii_data.replace('\n','@@@\n') + return ascii_data + + security.declarePrivate('dom2str') + def dom2str(self, xml_root=None): + """ + This function transform a DOM tree to string. + This function is only usefull for debugging. + """ + xml_str = StringIO() + PrettyPrint(xml_root, xml_str) + xml_string = xml_str.getvalue() + return xml_string + class ShopOrder(MMMShopOrder, Order): """ @@ -230,6 +323,9 @@ Un tissu est une resource variantable en couleur.""" if variation_value is not None: lineobj.setVariationValue(variation_value) return lineobj + def getProperty(self, key, d=None): + return Base.getProperty(self, key, d=None) + security.declarePublic('getOldTotalPrice') def getOldTotalPrice(self): """ @@ -256,6 +352,13 @@ Un tissu est une resource variantable en couleur.""" """ return self.getTotalPrice() + self.getTax() + security.declarePublic('getEuVat') + def getEuVat(self): + """ + Get the EU VAT code + """ + return self.getEUVat() + def _online_payment(self): """ This method is called by the bank @@ -308,6 +411,36 @@ Un tissu est une resource variantable en couleur.""" # VariationValue(variant=item.variant) return self.objectValues(('MMM Shop Order Line', 'ERP5 Shop Order Line')) + security.declareProtected(Permissions.View, 'getOwnerAccountId') + def getOwnerAccountId(self): + """ + This method get automaticaly the id of the member account that is the owner of the ShopOrder. + TODO : use local roles (getOwnerId | getOwner | getOwnerInfo) to reduce the code below + """ + # Construct the path of the Members folder + portal_types = getToolByName(self, 'portal_types') + root_site = portal_types.getPortalObject() + root_site_path = root_site.absolute_url(relative=1) + members_folder_path = root_site_path + "/Members" + members_folder = root_site.restrictedTraverse(members_folder_path) + # Search if the self object is in the member folder + object_path = self.absolute_url(relative=1) + splitted_path = object_path.split("/") + for i in range(len(splitted_path)): + if i != 0 : + test_path = "/".join(splitted_path[:-i]) + test_object = root_site.restrictedTraverse(test_path) + # Member folder found ! + if members_folder == test_object: + return splitted_path[i-1] + return None + + security.declareProtected(Permissions.View, 'getOrderId') + def getOrderId(self): + """ + This method get the id of the order. + """ + return self.getId() # Compatibility dynamic patch MMMShopOrder.hasEUTax = ShopOrder.hasEUTax @@ -336,4 +469,4 @@ class ComputerVariantValue(VariationValue): for i in self.variant[5:]: if i != '': result += "%s / " % i - return result + return result \ No newline at end of file