← Back to team overview

openerp-community team mailing list archive

[Merge] lp:~r-launchpad-njw-me-uk/openerp-xml-rpc-scripts/basictests into lp:openerp-xml-rpc-scripts

 

Nick White has proposed merging lp:~r-launchpad-njw-me-uk/openerp-xml-rpc-scripts/basictests into lp:openerp-xml-rpc-scripts.

Requested reviews:
  OpenERP Community (openerp-community)

For more details, see:
https://code.launchpad.net/~r-launchpad-njw-me-uk/openerp-xml-rpc-scripts/basictests/+merge/72584

Adds a collection of scripts which test some basic OpenERP functionality.
-- 
https://code.launchpad.net/~r-launchpad-njw-me-uk/openerp-xml-rpc-scripts/basictests/+merge/72584
Your team OpenERP Community is requested to review the proposed merge of lp:~r-launchpad-njw-me-uk/openerp-xml-rpc-scripts/basictests into lp:openerp-xml-rpc-scripts.
=== added directory 'basic_tests'
=== added file 'basic_tests/README'
--- basic_tests/README	1970-01-01 00:00:00 +0000
+++ basic_tests/README	2011-08-23 14:35:28 +0000
@@ -0,0 +1,41 @@
+# Overview
+
+These scripts test various basic key functionality of OpenERP. They
+aim to step through workflows of common processes.
+
+## Usage
+
+Each script is called the same way:
+
+  ./scriptname.py hostname database username password
+
+Upon exit scripts will return 0 on success, or 1 on failure.
+
+Alternatively, the credentials can be set in the 'oesettings' file,
+and all scripts can be run simultaneously with:
+
+  ./runalltests.sh
+
+Before running the test scripts, run createtestenv.py, which creates
+a test partner, test partner addresses, and a test product.
+
+After running the test scripts, run removetestthings.py to cancel
+and delete (where possible) things left over from tests in the
+database.
+
+## Test script overview
+
+newpurchaseorder.py
+	tests the creation of a purchase order
+
+receivepacking.py
+	tests the reception of a packing
+
+newsaleorder.py
+	tests the creation of a sale order
+
+sendpacking.py
+	tests the sending of a packing
+
+newinvoice.py
+	tests the creation of an invoice

=== added file 'basic_tests/createtestenv.py'
--- basic_tests/createtestenv.py	1970-01-01 00:00:00 +0000
+++ basic_tests/createtestenv.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+#
+# Creates a new partner, a product category, a product, and partner addresses.
+
+import sys
+import oeclient
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+daddrid = oe.create('res.partner.address', {'name': 'TEST DELIVERY ADDRESS', 'type': 'delivery'})
+print("Delivery address created, id %s" % (daddrid))
+
+iaddrid = oe.create('res.partner.address', {'name': 'TEST INVOICE ADDRESS', 'type': 'invoice'})
+print("Invoice address created, id %s" % (iaddrid))
+
+partid = oe.create('res.partner', {'name': 'TEST PARTNER', 'credit_limit': '100'})
+oe.write('res.partner', partid, {'address': [(6, 0, [daddrid, iaddrid])]})
+print("Partner created, id %s" % (partid))
+
+catid = oe.create('product.category', {'name': 'TEST CATEGORY'})
+print("Category created, id %s" % (catid))
+
+prodid = oe.create('product.product', {'name': 'TEST PRODUCT', 'categ_id': catid})
+print("Product created, id %s" % (prodid))
+
+prodid = oe.create('product.product', {'name': 'TEST PRODUCT', 'categ_id': catid})
+print("Product created, id %s" % (prodid))

=== added file 'basic_tests/newinvoice.py'
--- basic_tests/newinvoice.py	1970-01-01 00:00:00 +0000
+++ basic_tests/newinvoice.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Tests the creation of an invoice, based on a packing.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+
+pids = oe.search('stock.picking', [('address_id', '=', int(t['daddr'])), ('state','=','done'), ('invoice_state', '=', '2binvoiced')])
+if not pids:
+	print("Could not find packing owned by test partner which is to be invoiced")
+	print(" (run sendpacking test to create one)")
+	retcode = 1
+	exit(retcode)
+
+import xmlrpclib # needed to intercept exception
+print("Creating invoice from packing %s" % (pids[0]))
+try:
+	oe.object_execute('stock.picking', 'action_invoice_create', [pids[0]], t['sjournal'])
+	# this tries to return a dictionary, which fails due to xmlrpclib
+	# see https://bugs.launchpad.net/openobject-server/+bug/689575
+except xmlrpclib.Fault:
+	pass
+
+# invs won't be set, due to above bug, so search for the invoice
+pname = oe.read('stock.picking', pids[0], ['name'])
+invs = oe.search('account.invoice', [('origin', 'like', '%s%%' % (pname['name']))])
+
+if not invs:
+	print("Could not create invoice")
+	retcode = 1
+	exit(retcode)
+print("Invoice created, id %s" % (invs[0]))
+
+plineids = oe.search('stock.move', [('picking_id', '=', pids[0])])
+invlineids = oe.search('account.invoice.line', [('invoice_id', '=', invs[0])])
+
+pqs = {}
+iqs = {}
+for plid, ilid in zip(plineids, invlineids):
+	pq = oe.read('stock.move', plid, ['product_id', 'product_qty'])
+	pqs[pq['product_id'][0]] = pq['product_qty']
+	iq = oe.read('account.invoice.line', ilid, ['product_id', 'quantity'])
+	iqs[pq['product_id'][0]] = pq['product_qty']
+
+if iqs.keys() == pqs.keys():
+	print("Same products in picking (%s) and invoice (%s)" % (pqs.keys(), iqs.keys()))
+else:
+	print("Error: different products in picking (%s) and invoice (%s)" % (pqs.keys, iqs.keys))
+	retcode = 1
+
+for i in iqs.keys():
+	if pqs[i] == iqs[i]:
+		print("Same quantity for product id %s, %d in packing, %d in invoice" % (i, pqs[i], iqs[i]))
+	else:
+		print("Error: different quantity for product id %s, %d in packing, %d in invoice" % (i, pqs[i], iqs[i]))
+		retcode = 1
+
+print("Confirming invoice")
+oe.exec_workflow('account.invoice', 'invoice_open', invs[0])
+state = oe.read('account.invoice', invs[0], ['state'])['state']
+if state == 'open':
+	print("Invoice open")
+else:
+	print("Error: invoice is not open, it is in state %s" % (state))
+	retcode = 1
+
+exit(retcode)

=== added file 'basic_tests/newpurchaseorder.py'
--- basic_tests/newpurchaseorder.py	1970-01-01 00:00:00 +0000
+++ basic_tests/newpurchaseorder.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# Tests the creation of a purchase order.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+
+pid = oe.create('purchase.order', {'partner_id': t['partner'], 'dest_address_id': t['daddr'], 'partner_address_id': t['daddr'], 'pricelist_id': t['pricelist'], 'location_id': t['stockloc']})
+print("Purchase order created, id %s" % (pid))
+
+plid = oe.create('purchase.order.line', {'order_id': pid, 'product_id': t['prod'], 'product_uom': t['uom'], 'product_qty': t['lineqty'], 'price_unit': t['lineprice'], 'name': 'TEST LINE', 'date_planned': '2000-01-01'})
+print("Order line created, id %s" % (plid))
+
+oe.exec_workflow('purchase.order', 'purchase_confirm', pid)
+state = oe.read('purchase.order', pid, ['state'])['state']
+if state == 'confirmed':
+	print("Purchase order confirmed")
+else:
+	print("Purchase order not confirmed as expected; state is %s" % (state))
+	retcode = 1
+
+pavailpre = oe.read('product.product', [t['prod']], ['virtual_available'])[0]['virtual_available']
+pavailexpected = pavailpre + t['lineqty']
+
+oe.exec_workflow('purchase.order', 'purchase_approve', pid)
+state = oe.read('purchase.order', pid, ['state'])['state']
+if state == 'approved':
+	print("Purchase order approved")
+else:
+	print("Purchase order not approved as expected; state is %s" % (state))
+	retcode = 1
+
+pavailpost = oe.read('product.product', [t['prod']], ['virtual_available'])[0]['virtual_available']
+
+if pavailpost == pavailexpected:
+	print("Product available figure went up to %d as expected" % (pavailexpected))
+else:
+	print("Product available figure went up from %d to %d, not %d" % (pavailpre, pavailpost, pavailexpected))
+	retcode = 1
+
+exit(retcode)

=== added file 'basic_tests/newsaleorder.py'
--- basic_tests/newsaleorder.py	1970-01-01 00:00:00 +0000
+++ basic_tests/newsaleorder.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# Tests the creation of a sale order.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+
+oid = oe.create('sale.order', {'partner_id': t['partner'], 'partner_order_id': t['daddr'], 'partner_invoice_id': t['iaddr'], 'partner_shipping_id': t['daddr'], 'pricelist_id': t['pricelist']})
+print("Order created, id %s" % (oid))
+
+olid = oe.create('sale.order.line', {'order_id': oid, 'product_id': t['prod'], 'product_uom': t['uom'], 'product_uom_qty': t['lineqty'], 'price_unit': t['lineprice'], 'name': 'TEST LINE'})
+print("Order line created, id %s" % (olid))
+
+pavailpre = oe.read('product.product', [t['prod']], ['virtual_available'])[0]['virtual_available']
+pavailexpected = pavailpre - t['lineqty']
+
+oe.exec_workflow('sale.order', 'order_confirm', oid)
+state = oe.read('sale.order', oid, ['state'])['state']
+if state == 'progress':
+	print("Order confirmed")
+else:
+	print("Order not confirmed as expected (should be 'progress'); state is %s" % (state))
+	retcode = 1
+
+pavailpost = oe.read('product.product', [t['prod']], ['virtual_available'])[0]['virtual_available']
+
+if pavailpost == pavailexpected:
+	print("Product available figure went down to %d as expected" % (pavailexpected))
+else:
+	print("Product available figure went down from %d to %d, not %d" % (pavailpre, pavailpost, pavailexpected))
+	retcode = 1
+
+oname = oe.read('sale.order', [oid], ['name'])
+pids = oe.search('stock.picking', [('origin', '=', oname[0]['name'])])
+if pids:
+	print("Associated picking found, id %s" % (pids[0]))
+else:
+	print("No associated picking found")
+	retcode = 1
+
+exit(retcode)

=== added file 'basic_tests/oeclient.py'
--- basic_tests/oeclient.py	1970-01-01 00:00:00 +0000
+++ basic_tests/oeclient.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+
+# shell module to avoid having to use xmlrpclib directly
+
+import xmlrpclib
+
+class OpenERPClient:
+    common_client = None
+    object_client = None
+    uid = None
+    password = None
+    database = None
+    
+    def connect(self, hostname, database, username, password):
+        # preserve these for future calls
+        self.database = database
+        self.password = password
+
+        # some calls require the user to be logged in or strange errors amass
+        self.common_client = xmlrpclib.ServerProxy("http://%s:8069/xmlrpc/common"; % hostname, allow_none=True)
+        self.uid = self.common_client.login(database, "admin", password)
+
+        self.object_client = xmlrpclib.ServerProxy("http://%s:8069/xmlrpc/object"; % hostname, allow_none=True)
+        return self.uid
+
+    def search(self, object, args, context={}):
+        return self.object_execute(object, 'search', args, 0, None, None, context)
+
+    def read(self, object, ids, fields, context={}):
+        return self.object_execute(object, 'read', ids, fields, context)
+
+    def create(self, object, fields):
+        return self.object_execute(object, 'create', fields)
+
+    def write(self, object, ids, fields):
+        return self.object_execute(object, 'write', ids, fields)
+
+    def unlink(self, object, ids):
+        return self.object_execute(object, 'unlink', ids)
+
+    def copy(self, object, id_, default=None):
+        return self.object_execute(object, 'copy', id_, default)
+
+    # Fixme, args should be a splat-list or whatever
+    def object_execute(self, object, method, *args):
+        res = self.object_client.execute(
+            self.database, self.uid, self.password, object, method, *args
+        )
+        return res
+
+    def exec_workflow(self, object, signal, id):
+        res = self.object_client.exec_workflow(
+            self.database, self.uid, self.password, object, signal, id
+        )
+        return res

=== added file 'basic_tests/oesettings'
--- basic_tests/oesettings	1970-01-01 00:00:00 +0000
+++ basic_tests/oesettings	2011-08-23 14:35:28 +0000
@@ -0,0 +1,5 @@
+# set these according to your site
+host=localhost
+dbname=mydb
+oeuser=admin
+oepass=password

=== added file 'basic_tests/receivepacking.py'
--- basic_tests/receivepacking.py	1970-01-01 00:00:00 +0000
+++ basic_tests/receivepacking.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# Tests the reception of a packing.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+
+orderids = oe.search('purchase.order', [('partner_id','=',t['partner']),('state','=','approved')])
+if not orderids:
+	print("No purchase order found; run newpurchaseorder.py to create one")
+	exit(1)
+pids = oe.read('purchase.order', orderids[0], ['picking_ids'])['picking_ids']
+if not orderids:
+	print("No picking associated with purchase order found; remove any other test purchase orders and run newpurchaseorder.py")
+	exit(1)
+else:
+	pid = pids[0]
+
+pqtypre = oe.read('product.product', [t['prod']], ['qty_available'])[0]['qty_available']
+pqtyexpected = pqtypre + t['lineqty']
+
+oe.exec_workflow('stock.picking', 'button_done', pid)
+state = oe.read('stock.picking', pid, ['state'])['state']
+if state == 'done':
+	print("Picking %d done" % (pid))
+else:
+	print("Picking %d not done as expected; state is %s" % (pid, state))
+	retcode = 1
+
+pqtypost = oe.read('product.product', [t['prod']], ['qty_available'])[0]['qty_available']
+
+if pqtypost == pqtyexpected:
+	print("Product quantity figure went up to %d as expected" % (pqtyexpected))
+else:
+	print("Product quantity figure went up from %d to %d, not %d" % (pqtypre, pqtypost, pqtyexpected))
+	retcode = 1
+
+exit(retcode)

=== added file 'basic_tests/removetestthings.py'
--- basic_tests/removetestthings.py	1970-01-01 00:00:00 +0000
+++ basic_tests/removetestthings.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+#
+# Cancels all pickings, purchase orders, sale orders and invoices, and
+# deletes cancelled purchase orders, sale orders, and invoices, which
+# were created for the test partner.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+
+pids = oe.search('stock.picking', [('address_id', '=', t['daddr']), ('state', 'in', ['confirmed','assigned'])])
+if not pids:
+	print("No pickings found")
+
+for pid in pids:
+	oe.exec_workflow('stock.picking', 'button_cancel', pid)
+
+states = oe.read('stock.picking', pids, ['state'])
+for s in states:
+	if s['state'] == 'cancel':
+		print("Picking %s cancelled" % (s['id']))
+		# note cancelled pickings cannot be deleted
+	else:
+		print("Picking %s not cancelled as expected; state is %s" % (s['id'], s['state']))
+		retcode = 1
+
+
+saleids = oe.search('sale.order', [('partner_id', '=', t['partner']), ('state', '=', 'progress')])
+if not saleids:
+	print("No sale orders found")
+
+oe.object_execute('sale.order', 'action_cancel', saleids)
+
+states = oe.read('sale.order', saleids, ['state'])
+for s in states:
+	if s['state'] == 'cancel':
+		print("Sale order %s cancelled" % (s['id']))
+		oe.unlink('sale.order', [s['id']])
+		print("Sale order %s deleted" % (s['id']))
+	else:
+		print("Sale order %s not cancelled as expected; state is %s" % (s['id'], s['state']))
+		retcode = 1
+
+
+"""
+# purchase orders aren't set to done with current tests,
+# so don't bother deleting (they won't delete with done moves)
+pids = oe.search('purchase.order', [('partner_id', '=', t['partner']), ('state', 'in', ['approved','except_picking','except_invoice'])])
+if not pids:
+	print("No purchase orders found")
+print pids
+
+oe.object_execute('purchase.order', 'action_cancel', pids)
+
+states = oe.read('purchase.order', pids, ['state'])
+for s in states:
+	if s['state'] == 'cancel':
+		print("Purchase order %s cancelled" % (s['id']))
+		oe.unlink('purchase.order', [s['id']])
+		print("Purchase order %s deleted" % (s['id']))
+	else:
+		print("Purchase order %s not cancelled as expected; state is %s" % (s['id'], s['state']))
+		retcode = 1
+"""
+
+iids = oe.search('account.invoice', [('partner_id', '=', t['partner']), ('state', '=', 'open')])
+if not iids:
+	print("No invoices found")
+
+oe.object_execute('account.invoice', 'action_cancel', iids)
+
+states = oe.read('account.invoice', iids, ['state'])
+for s in states:
+	if s['state'] == 'cancel':
+		print("Invoice %s cancelled" % (s['id']))
+		oe.unlink('account.invoice', [s['id']])
+		print("Invoice %s deleted" % (s['id']))
+	else:
+		print("Invoice %s not cancelled as expected; state is %s" % (s['id'], s['state']))
+		retcode = 1
+
+
+exit(retcode)

=== added file 'basic_tests/runalltests.sh'
--- basic_tests/runalltests.sh	1970-01-01 00:00:00 +0000
+++ basic_tests/runalltests.sh	2011-08-23 14:35:28 +0000
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Runs all tests and summarises results.
+# 
+# Run createtestenv.py before running these tests for the first time.
+
+. oesettings
+
+tests='
+       newpurchaseorder.py
+       receivepacking.py
+       newsaleorder.py
+       sendpacking.py
+       newinvoice.py
+       removetestthings.py
+      '
+
+ret=0
+
+for i in $tests
+do
+	printf "%s " "$i"
+	python "$i" "$host" "$dbname" "$oeuser" "$oepass" > /dev/null 2>&1
+	if test $? -ne 0
+	then
+		echo "failed (run test separately for more details)"
+		ret=1
+	else
+		echo "succeeded"
+	fi
+done
+
+exit $ret

=== added file 'basic_tests/sendpacking.py'
--- basic_tests/sendpacking.py	1970-01-01 00:00:00 +0000
+++ basic_tests/sendpacking.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Tests the sending of a packing.
+
+import sys
+import oeclient
+import testconf
+
+usage = "%s host database username password" % (sys.argv[0])
+if len(sys.argv) != 5:
+	print(usage)
+	exit(1)
+
+oe = oeclient.OpenERPClient()
+oe.connect(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+
+retcode = 0
+
+t = testconf.gettestids(oe)
+
+orderids = oe.search('sale.order', [('partner_id','=',t['partner']),('state','=','progress')])
+if not orderids:
+	print("No sale order found; run newsaleorder.py to create one")
+	exit(1)
+pids = oe.read('sale.order', orderids[0], ['picking_ids'])['picking_ids']
+if not orderids:
+	print("No picking associated with sale order found; remove any other test sale orders and run newsaleorder.py")
+	exit(1)
+else:
+	pid = pids[0]
+
+oe.object_execute('stock.picking', 'action_assign', [pid])
+state = oe.read('stock.picking', pid, ['state'])['state']
+if state == 'assigned':
+	print("Picking available")
+else:
+	print("Picking not available as expected; state is %s" % (state))
+	retcode = 1
+
+pqtypre = oe.read('product.product', [t['prod']], ['qty_available'])[0]['qty_available']
+pqtyexpected = pqtypre - t['lineqty']
+
+oe.exec_workflow('stock.picking', 'button_done', pid)
+state = oe.read('stock.picking', pid, ['state'])['state']
+if state == 'done':
+	print("Picking done")
+else:
+	print("Picking not done as expected; state is %s" % (state))
+	retcode = 1
+
+pqtypost = oe.read('product.product', [t['prod']], ['qty_available'])[0]['qty_available']
+
+if pqtypost == pqtyexpected:
+	print("Product quantity figure went down to %d as expected" % (pqtyexpected))
+else:
+	print("Product quantity figure went down from %d to %d, not %d" % (pqtypre, pqtypost, pqtyexpected))
+	retcode = 1
+
+exit(retcode)

=== added file 'basic_tests/testconf.py'
--- basic_tests/testconf.py	1970-01-01 00:00:00 +0000
+++ basic_tests/testconf.py	2011-08-23 14:35:28 +0000
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+def gettestids(oe):
+	t = {}
+
+	# TODO: set these smartly, using a dictionary and a loop
+
+	partids = oe.search('res.partner', [('name','=','TEST PARTNER')])
+	if not partids:
+		print("Cannot find partner; make sure createtestenv.py has run")
+		exit(1)
+	t['partner'] = partids[0]
+
+	daddrids = oe.search('res.partner.address', [('name','=','TEST DELIVERY ADDRESS')])
+	if not daddrids:
+		print("Cannot find delivery address; make sure createtestenv.py has run")
+		exit(1)
+	t['daddr'] = daddrids[0]
+
+	iaddrids = oe.search('res.partner.address', [('name','=','TEST INVOICE ADDRESS')])
+	if not iaddrids:
+		print("Cannot find invoice address; make sure createtestenv.py has run")
+		exit(1)
+	t['iaddr'] = daddrids[0]
+
+	prodids = oe.search('product.product', [('name','=','TEST PRODUCT')])
+	if not prodids:
+		print("Cannot find product id; make sure createtestenv.py has run")
+		exit(1)
+	t['prod'] = prodids[0]
+
+	uomids = oe.search('product.uom', [('name','=','PCE')])
+	if not uomids:
+		print("Cannot find PCE UOM; at present these scripts need it")
+		exit(1)
+	t['uom'] = uomids[0]
+
+	slocids = oe.search('stock.location', [('active','=','true'),('usage','=','internal'),('name','=','Stock')])
+	if not slocids:
+		print("Cannot find internal stock location; at present these scripts need it")
+		exit(1)
+	t['stockloc'] = slocids[0]
+
+	clocids = oe.search('stock.location', [('active','=','true'),('usage','=','customer')])
+	if not clocids:
+		print("Cannot find customer location; at present these scripts need it")
+		exit(1)
+	t['cloc'] = clocids[0]
+
+	plistids = oe.search('stock.location', [('active','=','true')])
+	if not plistids:
+		print("Cannot find a price list; at present these scripts need it")
+		exit(1)
+	t['pricelist'] = plistids[0]
+
+	jids = oe.search('account.journal', [('active','=',True),('type','=','sale')])
+	if not jids:
+		print("Cannot find a sale account journal; at present these scripts need it")
+		exit(1)
+	t['sjournal'] = jids[0]
+
+	t['lineqty'] = 3
+	t['lineprice'] = 4
+
+	return t


Follow ups