def _save_soap_return(self, cr, uid, ids, file_id, filename, xml_node, action, context=None): file_obj = self.pool.get('stock.connect.file') event_obj = self.pool.get('stock.event') resp = file_obj.create( cr, uid, { 'content': xml_to_string(xml_node), 'name': filename, 'input': True, 'stock_connect_id': ids, 'res_id': file_id, 'model': 'stock.connect.file' }, context) event_obj.create( cr, uid, { 'event_code': 'yellowcubesoap_{0}'.format(action), 'res_id': resp, 'model': 'stock.connect.file', }, context) return
def _save_file(self, cr, uid, ids, name, _input, _type, data, context=None): if context is None: context = {} if not isinstance(ids, list): ids = [ids] file_obj = self.pool.get('stock.connect.file') if not isinstance(data, str): data = xml_to_string(data) if _type in [ 'BUR', 'WAR', 'WBA' ] and '<!-- Currently no {0}s available -->'.format(_type) in data: logger.debug('Ignoring empty {0} file'.format(_type)) return for _id in ids: file_obj.create(cr, uid, { 'name': name, 'input': _input, 'type': _type.lower(), 'binary_content': False, 'content': data, 'stock_connect_id': _id }, context=context)
def _send_item(self, cr, uid, ids, server, xml_node, action, schema_name=None, context=None): """ @param server: connection proxy to outside server @param xml_node: lxml xml element to send @param action: SOAP action to query @param schema_name: schema to validate the node against before sending, if set. @return: xml_return_message, error_message """ try: if schema_name: r = validate_xml(schema_name, xml_node, print_error=bool(server.config.debug)) if r: return None, r xml_kargs = {'pretty_print': True, 'xml_declaration': False} this = self.__this(cr, uid, ids, context) root = create_root('{{{soapenv}}}Envelope') ns = schema_namespaces['soapenv'] # 0 soapenv:Header xml_header = create_element('Header', ns=ns) body = create_element('Body', ns=ns) body.append(xml_node) root.append(xml_header) root.append(body) out_data = xml_to_string(root, **xml_kargs) parser = etree.XMLParser(remove_blank_text=True) out_data = xml_to_string(open_xml(out_data, repair=False, parser=parser), pretty_print=True) if this.yc_soapsec_key_path: out_data = self._sign_xml(out_data, keyfile=this.yc_soapsec_key_path, certfile=this.yc_soapsec_cert_path) with _soap_debug(this, action) as soap_debug: soap_debug.write('SENDING', out_data) r, namespace = server.transport.call( server.proxy, out_data, server.namespace, action, encoding=server.encoding, http_proxy=server.http_proxy, config=server.config, timeout=server.timeout) soap_debug.write('RECEIVING', r) response = etree.fromstring(r) body = response.xpath('//soapenv:Body', namespaces=schema_namespaces)[0] fault = body.xpath('soapenv:Fault', namespaces=schema_namespaces) if fault: return fault[0], xml_to_string(fault[0]).replace( '&', '&').replace('<', '<').replace('>', '>') return body[0], None except Exception as e: return None, format_exception(e) return None, 'Unknown error'
def _process_gen_response(self, cr, uid, ids, context=None): if context is None: context = {} if not isinstance(ids, list): ids = [ids] stock_connect_file_obj = self.pool.get('stock.connect.file') stock_connect = self.browse(cr, uid, ids[0], context=context) domain = [('stock_connect_id', '=', stock_connect.id), ('model', '=', 'stock.connect.file'), ('state', '=', 'draft'), ('type', '=', False), ('input', '=', True), ('error', '=', False)] gen_file_ids = stock_connect_file_obj.search(cr, uid, domain, context=context) for gen_file in stock_connect_file_obj.browse(cr, uid, gen_file_ids, context=context): # Find the elements and mark them if 'GEN_Response>' in gen_file.content: gen_file.write({'type': 'gen', 'state': 'ready'}) domain[2] = ('state', '=', 'ready') domain[3] = ('type', '=', 'gen') def __read_file(xml_node): return { 'type': nspath(xml, 'gen:MessageType')[0].text, 'ref': nspath(xml, 'gen:Reference')[0].text, 'status_text': nspath(xml, 'gen:StatusText')[0].text, 'status_code': int(nspath(xml, 'gen:StatusCode')[0].text), 'status_type': nspath(xml, 'gen:StatusType')[0].text, } server = self._get_proxy(cr, uid, ids, context=context) gen_file_ids = stock_connect_file_obj.search(cr, uid, domain, order='id ASC', context=context) for gen_file in stock_connect_file_obj.browse(cr, uid, gen_file_ids, context=context): # Process all the files try: original_file = stock_connect_file_obj.browse( cr, uid, gen_file.res_id, context) if original_file.server_ack: # Only process if required msg = _("Ignoring Response on behalf old ACK on file") logger.warning(msg) gen_file.write({ 'error': False, 'state': 'cancel', 'info': msg }) continue xml = open_xml(gen_file.content, repair=False) values = __read_file(xml) if values['status_type'] != 'S' or values['status_code'] > 100: # Don't re-process errors raise Exception(_("Error on Status response"), values['status_text']) elif values['status_code'] == 100: # If it was finished, don't reprocess gen_file.write({ 'state': 'done', 'info': values['status_text'], 'internal_index': values['status_code'] }) original_file.write({'server_ack': True}) else: # Send a request ns = schema_namespaces['gen_req'] xml_req = create_root('{{{gen_req}}}GEN_STATUS') xml_req.append( self._get_control_reference(cr, uid, ids, ns, values['type'], context=context)) xml_req.append( create_element('Reference', text=values['ref'], ns=ns)) xml_ret, err_ret = self._send_item( cr, uid, ids, server, xml_req, action='GetInsertArticleMasterDataStatus', schema_name='gen_req', context=context) if err_ret: # Write errors on file gen_file.write({'error': True, 'info': err_ret}) else: values_ret = __read_file(xml_ret) if values_ret['status_type'] != 'S' or values_ret[ 'status_code'] > 100: # Strange status codes are errors gen_file.write({ 'error': True, 'info': xml_to_string(xml_ret), 'internal_index': values_ret['status_code'] }) elif values_ret['status_code'] < 100: # Modify the file if pending, avoiding excess of inputs gen_file.write({ 'content': xml_to_string(xml_ret), 'internal_index': values_ret['status_code'] }) else: # Propagate end gen_file.write({ 'state': 'done', 'content': xml_to_string(xml_ret), 'info': values_ret['status_text'], 'internal_index': values_ret['status_code'] }) original_file.write({'server_ack': True}) except Exception as e: logger.error(format_exception(e)) gen_file.write({'error': True, 'info': format_exception(e)})