[MERGE] branch merged with lp:~openerp-dev/openobject-addons/uco-dev-addons1

bzr revid: mso@mso-20100513124516-avnhwd6ok8tg0asj
This commit is contained in:
mso 2010-05-13 18:15:16 +05:30
commit 7418c2a8f5
17 changed files with 1252 additions and 538 deletions

View File

@ -50,8 +50,10 @@
'wizard/auction_payer_sel_view.xml',
'wizard/auction_lots_sms_send_view.xml',
'wizard/auction_catalog_flagey_view.xml',
# 'wizard/auction_aie_send_view.xml',
# 'wizard/auction_aie_send_result_view.xml',
'wizard/auction_lots_buyer_map_view.xml',
# 'wizard/auction_lots_numerotate_view.xml',
'auction_view.xml',
'auction_report.xml',

View File

@ -31,8 +31,10 @@ import auction_lots_sms_send
import auction_catalog_flagey_report
#import auction_lots_cancel
#import auction_transfer_unsold_object
#import auction_aie_send
#import auction_aie_send_result
import auction_lots_buyer_map
#import auction_lots_numerotate
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,223 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#
# Does not properly work concurrently !!!
#
import base64
import mimetypes
import httplib
import threading
from tools.translate import _
from osv import fields,osv
class auction_lots_send_aie(osv.osv_memory):
_name = 'auction.lots.send.aie'
_descritption = 'Send to website'
def _date_get(self, cr, uid, context={}):
selection = context and context.get('selection')
if selection:
return [('','')] + selection
return [('','')]
_columns = {
'uname': fields.char('Login', size=64),
'password': fields.char('Password', size=64),
'objects': fields.integer('# of objects', readonly=True),
'lang': fields.selection([('fr','fr'),('ned','ned'),('eng','eng'),('de','de')],'Language'),
'numerotation': fields.selection([('prov','Provisoire'),('definite','Definitive (ordre catalogue)')],'Numerotation'),
'dates': fields.selection(_date_get,'Auction Date'),
'img_send': fields.boolean('Send Image also ?'),
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_lots_send_aie, self).default_get(cr, uid, fields, context=context)
if 'uname' in fields and context.get('uname',False):
res['uname'] = context.get('uname')
if 'password' in fields and context.get('password',False):
res['password'] = context.get('password')
return res
def _catalog_send(uname, passwd, lang, did, catalog):
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key,value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, key+'.pickle'))
L.append('Content-Type: application/octet-stream')
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
import httplib
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/catalog.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/catalog.cgi", (('uname',uname),('password',passwd),('did',did),('lang',lang)),(('file',catalog),))
def _photo_bin_send(uname, passwd, ref, did, photo_name, photo_data):
def get_content_type(filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, data) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % get_content_type(filename))
L.append('')
L.append(data)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/photo.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/photo.cgi", (('uname',uname),('ref',ref),('passwd',passwd),('did',did)),(('file',photo_name,photo_data),))
def _photos_send(cr, uid, uname, passwd, did, ids):
service = netsvc.LocalService("object_proxy")
for (ref,id) in ids:
# ids_attach = service.execute(db_name,uid, 'ir.attachment', 'search', [('res_model','=','auction.lots'), ('res_id', '=',id)])
datas = service.execute(cr.db_name,uid, 'auction.lots', 'read',[id], ['name','image'])
if len(datas):
bin = base64.decodestring(datas[0]['image'])
fname = datas[0]['name']
_photo_bin_send(uname, passwd, ref, did, fname, bin)
def get_dates(self, cr, uid, ids, context={}):
import httplib
data_obj = self.pool.get('ir.model.data')
conn = httplib.HTTPConnection('www.auction-in-europe.com')
datas = self.read(cr, uid, ids[0],['uname','password'])
conn.request("GET", "/aie_upload/dates_get.php?uname=%s&passwd=%s" % (datas['uname'], datas['password']))
response = conn.getresponse()
if response.status == 200:
def _date_decode(x):
return (x.split(' - ')[0], (' - '.join(x.split(' - ')[1:]).decode('latin1','replace').encode('utf-8','replace')))
context['selection'] = map(_date_decode, response.read().split('\n'))
self._date_get(cr, uid, context=context)
else:
raise osv.except_osv(_('Error'), _("Connection to WWW.Auction-in-Europe.com failed !"))
id1 = data_obj._get_id(cr, uid, 'auction', 'view_auction_lots_send')
res_id = data_obj.browse(cr, uid, id1, context=context).res_id
context.update(datas)
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'auction.lots.send.aie',
'views': [(res_id,'form')],
'type': 'ir.actions.act_window',
'target':'new',
'context': context
}
def _send(self, cr, uid, ids, context={}):
import pickle, thread, sql_db
cr.execute('select name,aie_categ from auction_lot_category')
vals = dict(cr.fetchall())
cr.close()
service = netsvc.LocalService("object_proxy")
lots = service.execute(cr.dbname, uid, 'auction.lots', 'read', context['active_ids'], ['obj_num','lot_num','obj_desc','bord_vnd_id','lot_est1','lot_est2','artist_id','lot_type','aie_categ'])
lots_ids = []
datas = self.read(cr, uid, ids[0],['uname','login','lang','numerotation','dates'])
for l in lots:
if datas['numerotation']=='prov':
l['ref']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
l['ref2']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
else:
l['ref']='%04d' % (l['obj_num'],)
l['ref2']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
if l['artist_id']:
l['artist_id'] = l['artist_id'][1]
else:
l['artist_id'] = ''
for n in ('obj_desc','artist_id','lot_type'):
try:
l[n]=l[n].decode('utf-8','replace').encode('latin1','replace')
except:
l[n]=''
del l['lot_num']
del l['obj_num']
del l['bord_vnd_id']
l['aie_categ'] = vals.get(l['lot_type'], False)
lots_ids.append((l['ref'], l['id']))
args = pickle.dumps(lots)
thread.start_new_thread(_catalog_send, (datas['uname'],datas['password'],datas['lang'],datas['dates'], args))
if(datas['form']['img_send']==True):
thread.start_new_thread(_photos_send, (cr.dbname, uid, datas['uname'], datas['password'],datas['dates'], lots_ids))
return {}
def send_pdf(self, cr, uid, ids, context):
threaded_calculation = threading.Thread(target=self._send, args=(cr, uid, ids, context))
threaded_calculation.start()
return {}
auction_lots_send_aie()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#
# Does not properly work concurrently !!!
#
import netsvc
from tools.translate import _
from osv import fields, osv
class auction_lots_pay(osv.osv_memory):
_name = 'auction.lots.send.aie.results'
_description = 'Send results to Auction-in-europe.com'
def _date_get(self, cr, uid, context={}):
selection = context and context.get('selection')
if selection:
return [('','')] + selection
return [('','')]
_columns = {
'uname': fields.char('Login', size=64),
'password': fields.char('Password', size=64),
'objects': fields.integer('# of objects'),
'dates': fields.selection(_date_get,'Auction Date'),
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_lots_pay, self).default_get(cr, uid, fields, context=context)
if 'uname' in fields and context.get('uname',False):
res['uname'] = context.get('uname')
if 'password' in fields and context.get('password',False):
res['password'] = context.get('password')
return res
def _catalog_send(self, uname, passwd, did, catalog):
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key,value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, key+'.pickle'))
L.append('Content-Type: application/octet-stream')
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
import httplib
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/catalog_result.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/catalog_result.cgi", (('uname',uname),('password',passwd),('did',did)),(('file',catalog),))
def get_dates(self, cr, uid, ids, context):
import httplib
conn = httplib.HTTPConnection('www.auction-in-europe.com')
data_obj = self.pool.get('ir.model.data')
datas = self.read(cr, uid, ids[0],['uname','password'])
conn.request("GET", "/aie_upload/dates_get_result.php?uname=%s&passwd=%s" % (datas['uname'], datas['password']))
response = conn.getresponse()
if response.status == 200:
def _date_decode(x):
return (x.split(' - ')[0], (' - '.join(x.split(' - ')[1:]).decode('latin1').encode('utf-8')))
context['selection'] = map(_date_decode, response.read().split('\n'))
self._date_get(cr, uid, context=context)
else:
raise osv.except_osv(_('Error'),
_("Connection to WWW.Auction-in-Europe.com failed !"))
id1 = data_obj._get_id(cr, uid, 'auction', 'view_auction_lots_send_result_send')
res_id = data_obj.browse(cr, uid, id1, context=context).res_id
context.update(datas)
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'auction.lots.send.aie.results',
'views': [(res_id,'form')],
'type': 'ir.actions.act_window',
'target':'new',
'context': context
}
def send(self, cr, uid, ids, context):
import pickle
service = netsvc.LocalService("object_proxy")
datas = self.read(cr, uid, ids[0],['uname','password','dates'])
lots = service.execute(cr.dbname, uid, 'auction.lots', 'read', context['active_ids'], ['obj_num','obj_price'])
args = pickle.dumps(lots)
self._catalog_send(datas['uname'], datas['password'], datas['dates'], args)
return {}
auction_lots_pay()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Auction lots send result -->
<record id="view_auction_lots_send_result_login" model="ir.ui.view">
<field name="name">Auction lots send result - Login</field>
<field name="model">auction.lots.send.aie.results</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Login">
<field name="uname"/>
<newline/>
<field name="password" password="True"/>
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="get_dates" string="Continue"
colspan="1" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
<act_window name="Send results to Auction-in-europe.com"
res_model="auction.lots.send.aie.results"
src_model="auction.lots"
view_mode="form"
view_id="view_auction_lots_send_result_login"
target="new"
key2="client_action_multi"
id="action_view_auction_lots_send_result_login"/>
<record id="view_auction_lots_send_result_send" model="ir.ui.view">
<field name="name">Auction lots send result - Send</field>
<field name="model">auction.lots.send.aie.results</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Login">
<field name="uname" readonly="1"/>
<field name="password" password="True" readonly="1"/>
<newline/>
<field name="objects" readonly="1"/>
<newline/>
<field name="dates" colspan="3"/>
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="send" string="Send on your website"
colspan="1" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Auction lots send result -->
<record id="view_auction_lots_send_login" model="ir.ui.view">
<field name="name">Auction lots send - Login</field>
<field name="model">auction.lots.send.aie</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Login">
<field name="uname"/>
<newline/>
<field name="password" password="True"/>
<separator colspan="4"/>
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="get_dates" string="Continue"
colspan="1" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
<act_window name="Send to website"
res_model="auction.lots.send.aie"
src_model="auction.lots"
view_mode="form"
view_id="view_auction_lots_send_login"
target="new"
key2="client_action_multi"
id="action_view_auction_lots_send_login"/>
<record id="view_auction_lots_send" model="ir.ui.view">
<field name="name">Auction lots - Send</field>
<field name="model">auction.lots.send.aie</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Login">
<field name="uname" readonly="1"/>
<field name="password" password="True" readonly="1"/>
<newline/>
<field name="objects"/>
<field name="lang"/>
<field name="numerotation"/>
<field name="img_send"/>
<newline/>
<field name="dates" colspan="3"/>
<separator colspan="4"/>
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="send_pdf" string="Send on your website"
colspan="1" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import netsvc
import sql_db
from osv import osv, fields
from tools.translate import _
class auction_lots_numerotate_per_lot(osv.osv_memory):
_name = 'auction.lots.numerotate'
_description = 'Numerotation (per lot)'
_columns = {
'bord_vnd_id': fields.many2one('auction.deposit', 'Depositer Inventory', required=True),
'lot_num': fields.integer('Inventory Number', readonly=True),
'lot_est1': fields.float('Minimum Estimation', readonly=True),
'lot_est2': fields.float('Maximum Estimation', readonly=True),
'name': fields.char('Short Description', size=64, readonly=True),
'obj_desc': fields.text('Description', readonly=True),
'obj_num': fields.integer('Catalog Number', required=True)
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(auction_lots_numerotate_per_lot, self).default_get(cr, uid, fields, context=context)
active_id = context.get('active_id',False)
active_model = context.get('active_model')
if active_id and (active_model and active_model!='auction.lots'):
return res
lots_obj = self.pool.get('auction.lots')
lots = lots_obj.browse(cr, uid, active_id)
if 'bord_vnd_id' in fields and context.get('bord_vnd_id',False):
res['bord_vnd_id'] = context.get('bord_vnd_id')
if 'lot_num' in fields and context.get('lot_num',False):
res['lot_num'] = context.get('lot_num')
if 'lot_est1' in fields:
res['lot_est1'] = lots.lot_est1
if 'lot_est2' in fields:
res['lot_est2'] = lots.lot_est2
if 'name' in fields:
res['name'] = lots.name
if 'obj_desc' in fields:
res['obj_desc'] = lots.obj_desc
if 'obj_num' in fields:
res['obj_num'] = lots.obj_num
return res
def open_init_form(self, cr, uid, ids, context={}):
record_ids = context and context.get('active_ids',False) or False
assert record_ids, _('Active IDs not Found')
data_obj = self.pool.get('ir.model.data')
view_id = data_obj._get_id(cr, uid, 'auction', 'view_auction_numerotate')
if view_id:
res_id = data_obj.browse(cr, uid, view_id, context=context).res_id
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'auction.lots.numerotate',
'res_id' : False,
'views': [(res_id,'form')],
'type': 'ir.actions.act_window',
'target':'new',
'context': context
}
def numerotate(self, cr, uid, ids, context={}):
record_ids = context and context.get('active_ids',False) or False
assert record_ids, _('Active IDs not Found')
datas = self.read(cr, uid, ids[0], ['bord_vnd_id','lot_num','obj_num'])
data_obj = self.pool.get('ir.model.data')
lots_obj = self.pool.get('auction.lots')
res = lots_obj.search(cr,uid,[('bord_vnd_id','=',datas['bord_vnd_id']),
('lot_num','=',int(datas['lot_num']))])
found = [r for r in res if r in record_ids]
if len(found)==0:
raise osv.except_osv('UserError', 'This record does not exist !')
lots_obj.write(cr, uid, found, {'obj_num':int(datas['obj_num'])} )
view_id = data_obj._get_id(cr, uid, 'auction', 'view_auction_numerotate')
if view_id:
res_id = data_obj.browse(cr, uid, view_id, context=context).res_id
context.update(datas)
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'auction.lots.numerotate',
'res_id' : False,
'views': [(res_id,'form')],
'type': 'ir.actions.act_window',
'target':'new',
'context': context
}
def read_record(self, cr, uid, ids, context={}):
record_ids = context and context.get('active_ids',False) or False
assert record_ids, _('Active IDs not Found')
datas = self.read(cr, uid, ids[0], ['bord_vnd_id','lot_num'])
lots_obj = self.pool.get('auction.lots')
res = lots_obj.search(cr, uid, [('bord_vnd_id','=',datas['bord_vnd_id']),
('lot_num','=',int(datas['lot_num']))])
found = [r for r in res if r in record_ids]
if len(found)==0:
raise osv.except_osv('UserError', 'This record does not exist !')
lots_datas = lots_obj.read(cr, uid, found,
['obj_num', 'name', 'lot_est1',
'lot_est2', 'obj_desc'])
return lots_datas[0]
def test_exist(self, cr, uid, ids, context={}):
record_ids = context and context.get('active_ids',False) or False
assert record_ids, _('Active IDs not Found')
data_obj = self.pool.get('ir.model.data')
datas = self.read(cr, uid, ids[0], ['bord_vnd_id','lot_num'])
res = self.pool.get('auction.lots').search(cr, uid,
[('bord_vnd_id','=',datas['bord_vnd_id']),
('lot_num','=',int(datas['lot_num']))])
found = [r for r in res if r in record_ids]
if len(found)==0:
raise osv.except_osv('Error', 'This lot does not exist !')
view_id = data_obj._get_id(cr, uid, 'auction', 'view_auction_lots_numerotate_second')
if view_id:
res_id = data_obj.browse(cr, uid, view_id, context=context).res_id
context.update(datas)
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'auction.lots.numerotate',
'res_id' : False,
'views': [(res_id,'form')],
'type': 'ir.actions.act_window',
'target':'new',
'context' : context
}
auction_lots_numerotate_per_lot()
class auction_lots_numerotate(osv.osv_memory):
_name = 'auction.lots.numerotate_cont'
_description = 'Numerotation (automatic)'
_columns = {
'number': fields.integer('First Number', required=True)
}
def numerotate_cont(self, cr, uid, ids, context={}):
record_ids = context and context.get('active_ids',False) or False
assert record_ids, _('Active IDs not Found')
datas = self.read(cr, uid, ids[0], ['number'])
nbr = int(datas['number'])
lots_obj = self.pool.get('auction.lots')
rec_ids = lots_obj.browse(cr, uid, record_ids)
for rec_id in rec_ids:
lots_obj.write(cr, uid, [rec_id.id], {'obj_num':nbr})
nbr+=1
return {}
auction_lots_numerotate()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Numerotation (per lot) -->
<record id="view_auction_numerotate" model="ir.ui.view">
<field name="name">auction.lots.numerotate.open</field>
<field name="model">auction.lots.numerotate</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Catalog Numerotation" >
<separator string="Object Reference" colspan="4"/>
<field name="bord_vnd_id"/>
<newline/>
<field name="lot_num" readonly="False" required="True"/>
<separator colspan="4"/>
<group col="4" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Exit" />
<button name="test_exist" string="Continue"
colspan="2" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
<act_window name="Numerotation (per lot)"
res_model="auction.lots.numerotate"
src_model="auction.lots"
view_id="view_auction_numerotate"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_view_auction_lots_numerotate"/>
<record id="view_auction_lots_numerotate_second" model="ir.ui.view">
<field name="name">auction.lots.numerotate.second</field>
<field name="model">auction.lots.numerotate</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Catalog Numerotation" >
<group>
<separator string="Object Reference" colspan="4"/>
<field name="bord_vnd_id" readonly="1"/>
<field name="lot_num" readonly="1"/>
<field name="name" readonly="1" colspan="3"/>
<field name="obj_desc" readonly="1" colspan="3"/>
<field name="lot_est1" readonly="1"/>
<field name="lot_est2" readonly="1"/>
<separator string="Object Reference" colspan="4"/>
<field name="obj_num"/>
</group>
<newline/>
<separator colspan="4"/>
<group col="4" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Exit" />
<button name="open_init_form" string="Back" type="object"
icon="gtk-go-back"/>
<button name="numerotate" string="Numerotate"
type="object" icon="gtk-go-forward"/>
</group>
</form>
</field>
</record>
<record id="action_auction_lots_numerotate" model="ir.actions.act_window">
<field name="name">Numerotation (per lot)</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">auction.lots.numerotate</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_auction_lots_numerotate_second"/>
<field name="target">new</field>
</record>
<record id="view_auction_numerotate_not_exist" model="ir.ui.view">
<field name="name">auction.lots.numerotate.not_exist</field>
<field name="model">auction.lots.numerotate</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Catalog Numerotation">
<label string="This lot does not exist !" colspan="4"/>
<group col="4" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Exit" />
<button name="open_init_form" string="Retry" type="object"
icon="gtk-go-back"/>
</group>
</form>
</field>
</record>
<record id="action_auction_lots_numerotate_not_exist" model="ir.actions.act_window">
<field name="name">Numerotation - Not Exist</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">auction.lots.numerotate</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_auction_numerotate_not_exist"/>
<field name="target">new</field>
</record>
<record id="view_auction_numerotate_cont" model="ir.ui.view">
<field name="name">Numerotation (automatic)</field>
<field name="model">auction.lots.numerotate_cont</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Catalog Numerotation" >
<field name="number" colspan="4"/>
<separator colspan="4"/>
<group col="4" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Exit" />
<button name="numerotate_cont" string="Numerotation"
colspan="2" type="object" icon="gtk-go-forward" />
</group>
</form>
</field>
</record>
<act_window name="Numerotation (automatic)"
res_model="auction.lots.numerotate_cont"
src_model="auction.lots"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_view_auction_numerotate_cont"/>
</data>
</openerp>

View File

@ -1,232 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#
# Does not properly work concurently !!!
#
import pooler
import wizard
import netsvc
import base64
import mimetypes
import httplib
import threading
from tools.translate import _
login_form = '''<?xml version="1.0"?>
<form title="Login">
<field name="uname"></field>
<newline/>
<field name="password"></field>
</form>'''
send_form = '''<?xml version="1.0"?>
<form title="Selection">
<field name="uname"></field>
<field name="password"></field>
<newline/>
<field name="objects"></field>
<field name="lang"></field>
<field name="numerotation"></field>
<field name="img_send"></field>
<newline/>
<field name="dates" colspan="3"></field>
</form>'''
login_fields = {
'uname': {'string':'Login', 'type':'char'},
'password': {'string':'Password', 'type':'char'},
'numerotation': {'string':'Numerotation', 'type':'selection', 'selection':[('prov','Provisoire'),('definite','Definitive (ordre catalogue)')]},
'dates': {'string':'Auction Date', 'type':'selection', 'selection':[]}
}
send_fields = {
'uname': {'string':'Login', 'type':'char', 'readonly':True},
'password': {'string':'Password', 'type':'char', 'readonly':True},
'objects': {'string':'# of objects', 'type':'integer', 'readonly':True},
'lang': {'string':'Langage', 'type':'selection', 'selection':[('fr','fr'),('ned','ned'),('eng','eng'),('de','de')]},
'numerotation': {'string':'Numerotation', 'type':'selection', 'selection':[('prov','Provisoire'),('definite','Definitive (ordre catalogue)')]},
'dates': {'string':'Auction Date', 'type':'selection', 'selection':[]},
'img_send': {'string':'Send Image also ?', 'type':'boolean'}
}
def _catalog_send(uname, passwd, lang, did, catalog):
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key,value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, key+'.pickle'))
L.append('Content-Type: application/octet-stream')
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
import httplib
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/catalog.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/catalog.cgi", (('uname',uname),('password',passwd),('did',did),('lang',lang)),(('file',catalog),))
def _photo_bin_send(uname, passwd, ref, did, photo_name, photo_data):
def get_content_type(filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, data) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % get_content_type(filename))
L.append('')
L.append(data)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/photo.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/photo.cgi", (('uname',uname),('ref',ref),('passwd',passwd),('did',did)),(('file',photo_name,photo_data),))
def _photos_send(cr,uid, uname, passwd, did, ids):
for (ref,id) in ids:
service = netsvc.LocalService("object_proxy")
# ids_attach = service.execute(db_name,uid, 'ir.attachment', 'search', [('res_model','=','auction.lots'), ('res_id', '=',id)])
datas = service.execute(cr.db_name,uid, 'auction.lots', 'read',[id], ['name','image'])
if len(datas):
bin = base64.decodestring(datas[0]['image'])
fname = datas[0]['name']
_photo_bin_send(uname, passwd, ref, did, fname, bin)
def _get_dates(self,cr,uid, datas,context={}):
global send_fields
import httplib
conn = httplib.HTTPConnection('www.auction-in-europe.com')
conn.request("GET", "/aie_upload/dates_get.php?uname=%s&passwd=%s" % (datas['form']['uname'], datas['form']['password']))
response = conn.getresponse()
if response.status == 200:
def _date_decode(x):
return (x.split(' - ')[0], (' - '.join(x.split(' - ')[1:]).decode('latin1','replace').encode('utf-8','replace')))
send_fields['dates']['selection'] = map(_date_decode, response.read().split('\n'))
else:
raise wizard.except_wizard(_('Error'), _("Connection to WWW.Auction-in-Europe.com failed !"))
return {'objects':len(datas['ids'])}
def _send(self,db_name,uid, datas,context={}):
import pickle, thread, sql_db
#cr = pooler.get_db(cr.dbname).cursor()
# cr=sql_db.db.cursor()
cr = pooler.get_db(db_name).cursor()
cr.execute('select name,aie_categ from auction_lot_category')
vals = dict(cr.fetchall())
cr.close()
service = netsvc.LocalService("object_proxy")
lots = service.execute(cr.dbname,uid, 'auction.lots', 'read', datas['ids'], ['obj_num','lot_num','obj_desc','bord_vnd_id','lot_est1','lot_est2','artist_id','lot_type','aie_categ'])
ids = []
for l in lots:
if datas['form']['numerotation']=='prov':
l['ref']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
l['ref2']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
else:
l['ref']='%04d' % (l['obj_num'],)
l['ref2']='%s%03d' % (l['bord_vnd_id'][1],l['lot_num'])
if l['artist_id']:
l['artist_id'] = l['artist_id'][1]
else:
l['artist_id'] = ''
for n in ('obj_desc','artist_id','lot_type'):
try:
l[n]=l[n].decode('utf-8','replace').encode('latin1','replace')
except:
l[n]=''
del l['lot_num']
del l['obj_num']
del l['bord_vnd_id']
l['aie_categ'] = vals.get(l['lot_type'], False)
ids.append((l['ref'], l['id']))
args = pickle.dumps(lots)
thread.start_new_thread(_catalog_send, (datas['form']['uname'],datas['form']['password'],datas['form']['lang'],datas['form']['dates'], args))
if(datas['form']['img_send']==True):
thread.start_new_thread(_photos_send, (cr.dbname,uid, datas['form']['uname'],datas['form']['password'],datas['form']['dates'], ids))
return {}
def _send_pdf(self, cr, uid, data, context):
threaded_calculation = threading.Thread(target=_send, args=(self, cr.dbname, uid, data, context))
threaded_calculation.start()
return {}
class wiz_auc_lots_pay(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':login_form, 'fields': login_fields, 'state':[('date_ask','Continue'),('end','Cancel')]}
},
'date_ask': {
'actions': [_get_dates],
'result': {'type': 'form', 'arch':send_form, 'fields': send_fields, 'state':[('send','Send on your website'),('end','Cancel')]}
},
'send': {
'actions': [_send_pdf],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_auc_lots_pay('auction.lots.send.aie');
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,137 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#
# Does not properly work concurently !!!
#
import wizard
import netsvc
from tools.translate import _
login_form = '''<?xml version="1.0"?>
<form title="Login">
<field name="uname"></field>
<newline/>
<field name="password"></field>
</form>'''
send_form = '''<?xml version="1.0"?>
<form title="Selection">
<field name="uname"></field>
<field name="password"></field>
<newline/>
<field name="objects"></field>
<newline/>
<field name="dates" colspan="3"></field>
</form>'''
login_fields = {
'uname': {'string':'Login', 'type':'char'},
'password': {'string':'Password', 'type':'char'},
'dates': {'string':'Auction Date', 'type':'selection', 'selection':[]}
}
send_fields = {
'uname': {'string':'Login', 'type':'char', 'readonly':True},
'password': {'string':'Password', 'type':'char', 'readonly':True},
'objects': {'string':'# of objects', 'type':'integer', 'readonly':True},
'dates': {'string':'Auction Date', 'type':'selection', 'selection':[]}
}
def _catalog_send(uname, passwd, did, catalog):
def post_multipart(host, selector, fields, files):
def encode_multipart_formdata(fields, files):
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key,value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, key+'.pickle'))
L.append('Content-Type: application/octet-stream')
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
content_type, body = encode_multipart_formdata(fields, files)
import httplib
headers = {"Content-type": content_type, "Accept": "*/*"}
conn = httplib.HTTPConnection(host)
conn.request("POST", '/bin/catalog_result.cgi', body, headers = headers)
response = conn.getresponse()
val = response.status
conn.close()
return val
return post_multipart('auction-in-europe.com', "/bin/catalog_result.cgi", (('uname',uname),('password',passwd),('did',did)),(('file',catalog),))
def _get_dates(self,cr,uid, datas, context):
global send_fields
import httplib
conn = httplib.HTTPConnection('www.auction-in-europe.com')
conn.request("GET", "/aie_upload/dates_get_result.php?uname=%s&passwd=%s" % (datas['form']['uname'], datas['form']['password']))
response = conn.getresponse()
if response.status == 200:
def _date_decode(x):
return (x.split(' - ')[0], (' - '.join(x.split(' - ')[1:]).decode('latin1').encode('utf-8')))
send_fields['dates']['selection'] = map(_date_decode, response.read().split('\n'))
else:
raise wizard.except_wizard(_('Error'),
_("Connection to WWW.Auction-in-Europe.com failed !"))
return {'objects':len(datas['ids'])}
def _send(self,cr,uid, datas, context):
import pickle
service = netsvc.LocalService("object_proxy")
lots = service.execute(cr.dbname,uid, 'auction.lots', 'read', datas['ids'], ['obj_num','obj_price'])
args = pickle.dumps(lots)
_catalog_send(datas['form']['uname'],datas['form']['password'], datas['form']['dates'], args)
return {}
class wiz_auc_lots_pay(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':login_form, 'fields': login_fields, 'state':[('date_ask','Continue'),('end','Cancel')]}
},
'date_ask': {
'actions': [_get_dates],
'result': {'type': 'form', 'arch':send_form, 'fields': send_fields, 'state':[('send','Send on your website'),('end','Cancel')]}
},
'send': {
'actions': [_send],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_auc_lots_pay('auction.lots.send.aie.results');
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,154 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import netsvc
import pooler
import sql_db
numerotate_form_cont = '''<?xml version="1.0"?>
<form title="%s">
<field name="number" string="%s"/>
</form>''' % ('Continuous Numerotation','First Number')
numerotate_fields_cont = {
'number': {'string':'First Number', 'type':'integer', 'required':True}
}
numerotate_not_exist = '''<?xml version="1.0"?>
<form title="%s">
<label string="This lot does not exist !" colspan="4"/>
</form>''' % ('Catalog Numerotation',)
numerotate_form = '''<?xml version="1.0"?>
<form title="%s">
<separator string="%s" colspan="4"/>
<field name="bord_vnd_id"/>
<newline/>
<field name="lot_num"/>
</form>''' % ('Catalog Numerotation','Object Reference')
numerotate_fields = {
'bord_vnd_id': {'string':'Depositer Inventory', 'type':'many2one', 'required':True, 'relation':'auction.deposit'},
'lot_num': {'string':'Lot Number', 'type':'integer', 'required':True},
}
numerotate_form2 = '''<?xml version="1.0"?>
<form title="%s">
<group>
<separator string="%s" colspan="4"/>
<field name="bord_vnd_id" readonly="1"/>
<field name="lot_num" readonly="1"/>
<field name="name" readonly="1" colspan="3"/>
<field name="obj_desc" readonly="1" colspan="3"/>
<field name="lot_est1" readonly="1"/>
<field name="lot_est2" readonly="1"/>
<separator string="%s" colspan="4"/>
<field name="obj_num"/>
</group>
</form>''' % ('Catalog Numerotation','Object Reference','Object Reference')
numerotate_fields2 = {
'bord_vnd_id': {'string':'Object Inventory', 'type':'many2one', 'relation':'auction.deposit', 'readonly':True},
'lot_num': {'string':'Inventory Number', 'type':'integer', 'readonly':True},
'lot_est1': {'string':'Minimum Estimation', 'type':'float', 'readonly':True},
'lot_est2': {'string':'Maximum Estimation', 'type':'float', 'readonly':True},
'name': {'string':'Short Description', 'type':'char', 'size':64, 'readonly':True},
'obj_desc': {'string':'Description', 'type':'text', 'readonly':True},
'obj_num': {'string':'Catalog Number', 'type':'integer', 'required':True}
}
def _read_record(self,cr,uid,datas,context={}):
form = datas['form']
res = pooler.get_pool(cr.dbname).get('auction.lots').search(cr,uid,[('bord_vnd_id','=',form['bord_vnd_id']), ('lot_num','=',int(form['lot_num']))])
found = [r for r in res if r in datas['ids']]
if len(found)==0:
raise wizard.except_wizard('UserError', 'This record does not exist !')
datas = pooler.get_pool(cr.dbname).get('auction.lots').read(cr,uid,found,['obj_num', 'name', 'lot_est1', 'lot_est2', 'obj_desc'])
return datas[0]
def _test_exist(self,cr,uid,datas,context={}):
form = datas['form']
res = pooler.get_pool(cr.dbname).get('auction.lots').search(cr,uid,[('bord_vnd_id','=',form['bord_vnd_id']), ('lot_num','=',int(form['lot_num']))])
found = [r for r in res if r in datas['ids']]
if len(found)==0:
return 'not_exist'
return 'search'
def _numerotate(self,cr,uid,datas,context={}):
form = datas['form']
res = pooler.get_pool(cr.dbname).get('auction.lots').search(cr,uid,[('bord_vnd_id','=',form['bord_vnd_id']), ('lot_num','=',int(form['lot_num']))])
found = [r for r in res if r in datas['ids']]
if len(found)==0:
raise wizard.except_wizard('UserError', 'This record does not exist !')
pooler.get_pool(cr.dbname).get('auction.lots').write(cr,uid,found,{'obj_num':int(form['obj_num'])} )
return {'lot_inv':'', 'lot_num':''}
def _numerotate_cont(self,cr,uid,datas,context={}):
nbr = int(datas['form']['number'])
refs = pooler.get_pool(cr.dbname).get('auction.lots')
rec_ids = refs.browse(cr,uid,datas['ids'])
for rec_id in rec_ids:
refs.write(cr,uid,[rec_id.id],{'obj_num':nbr})
nbr+=1
return {}
class wiz_auc_lots_numerotate(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':numerotate_form, 'fields': numerotate_fields, 'state':[('end','Cancel'),('choice','Continue')]}
},
'search': {
'actions': [_read_record],
'result': {'type': 'form', 'arch':numerotate_form2, 'fields': numerotate_fields2, 'state':[('end','Exit'),('init','Back'),('set_number','Numerotate')]}
},
'choice' : {
'actions' : [],
'result' : {'type' : 'choice', 'next_state': _test_exist }
},
'not_exist' : {
'actions': [],
'result': {'type': 'form', 'arch':numerotate_not_exist, 'fields': {}, 'state':[('end','Exit'),('init','Retry')]}
},
'set_number': {
'actions': [_numerotate],
'result': {'type': 'state', 'state':'init'}
}
}
wiz_auc_lots_numerotate('auction.lots.numerotate');
class wiz_auc_lots_numerotate(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':numerotate_form_cont, 'fields': numerotate_fields_cont, 'state':[('end','Exit'),('set_number','Numerotation')]}
},
'set_number': {
'actions': [_numerotate_cont],
'result': {'type': 'state', 'state':'end'}
}
}
wiz_auc_lots_numerotate('auction.lots.numerotate_cont');
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -77,7 +77,11 @@
'report/mrp_production_order_view.xml',
],
'demo_xml': ['mrp_demo.xml', 'mrp_order_point.xml'],
# 'test': ['test/mrp_phantom_bom.yml','test/mrp_production_order.yml'],
'test': [
'test/mrp_phantom_bom.yml',
'test/mrp_production_order.yml',
'test/mrp_procurement.yml'
],
'installable': True,
'active': False,
'certificate': '0032052481373',

View File

@ -2,7 +2,7 @@
In order to test the mrp phantom bom type in OpenERP, I will create products
and then I will create Phantom bom structure for those products.
-
I create the products required to produce some orange juices: Oranges, Sugar and Water.
I create the products required to produce some orange juices with Oranges, Sugar and Water.
-
!record {model: product.uom, id: product_uom_litre0}:
category_id: product.product_uom_categ_kgm
@ -129,7 +129,6 @@
date_planned: '2010-04-16 15:53:36'
location_dest_id: stock.stock_location_output
location_src_id: stock.stock_location_stock
name: MO/00002
product_id: product_product_orangejuice0
product_qty: 100.0
product_uom: product_uom_litre0
@ -171,7 +170,7 @@
-
!python {model: mrp.procurement}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('origin','=',':MO/00002')])
proc_ids = self.search(cr, uid, [('state','!=','cofirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
@ -196,7 +195,7 @@
!python {model: purchase.order}: |
from tools.translate import _
import netsvc
purch_ids = self.search(cr, uid, [('origin','in',['SCHEDULER','OP/00002','OP/00003'])])
purch_ids = self.search(cr, uid, [('state','=','draft')])
assert purch_ids, _('No Purchase Orders were made!')
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
@ -207,7 +206,7 @@
!python {model: purchase.order}: |
from tools.translate import _
import netsvc
purch_ids = self.search(cr, uid, [('origin','in',['SCHEDULER','OP/00002','OP/00003']),('state','=','confirmed')])
purch_ids = self.search(cr, uid, [('state','=','confirmed')])
assert purch_ids, _('No Confirmed Purchase Orders found!')
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
@ -217,7 +216,7 @@
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('origin','in',['PO00001:SCHEDULER','PO00002:SCHEDULER','PO00003:OP/00002','PO00004:OP/00003']),('type','=','in')])
pick_ids = self.search(cr, uid, [('type','=','in')])
assert pick_ids, _('No Incoming Shipments found!')
-
I receive both the products. My incoming pickings are done.
@ -229,6 +228,7 @@
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
picking_ids = pick_obj.search(cr, uid, [('origin','in',['PO00001:SCHEDULER','PO00002:SCHEDULER','PO00003:OP/00002','PO00004:OP/00003']),('type','=','in')])
self.do_partial(cr, uid, [1],context={'active_ids': picking_ids})
picking_ids = pick_obj.search(cr, uid, [('type','=','in')])
self.view_init(cr, uid, ['date','partner_id','address_id'],context={'active_ids': picking_ids})
self.do_partial(cr, uid, [1], context={'active_ids': picking_ids})

View File

@ -0,0 +1,336 @@
-
In order to test the flow of procurement orders. I will put some orders with
different procurement methods. I have installed sale, mrp and purchase modules.
-
I am creating products.
-
Creating a product.product record
-
!record {model: product.product, id: product_product_shirt0}:
categ_id: product.cat1
cost_method: standard
list_price: 350.0
mes_type: fixed
name: Shirt
procure_method: make_to_stock
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
standard_price: 300.0
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
Creating a product.product record
-
!record {model: product.product, id: product_product_cloth0}:
categ_id: product.cat1
cost_method: standard
mes_type: fixed
name: Cloth
procure_method: make_to_order
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
seller_ids:
- delay: 1
name: base.res_partner_maxtor
qty: 300.0
standard_price: 1.0
supply_method: buy
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
Creating a product.product record
-
!record {model: product.product, id: product_product_buttons0}:
categ_id: product.cat1
cost_method: standard
mes_type: fixed
name: Buttons
procure_method: make_to_stock
property_stock_inventory: stock.location_inventory
property_stock_procurement: stock.location_procurement
property_stock_production: stock.location_production
seller_delay: '1'
seller_ids:
- delay: 1
name: base.res_partner_asus
qty: 100.0
standard_price: 1.0
supply_method: buy
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
volume: 0.0
warranty: 0.0
weight: 0.0
weight_net: 0.0
-
I am creating bills of material for 'Shirt'.
-
Creating a mrp.bom record
-
!record {model: mrp.bom, id: mrp_bom_shirt0}:
bom_lines:
- company_id: base.main_company
name: Cloth
product_efficiency: 1.0
product_id: product_product_cloth0
product_qty: 1.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
sequence: 0.0
type: normal
- company_id: base.main_company
name: Buttons
product_efficiency: 1.0
product_id: product_product_buttons0
product_qty: 8.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
sequence: 0.0
type: normal
company_id: base.main_company
name: Shirt
product_efficiency: 1.0
product_id: product_product_shirt0
product_qty: 1.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
sequence: 0.0
type: normal
-
I create minimum stock rule for product Buttons
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}:
company_id: base.main_company
location_id: stock.stock_location_stock
logic: max
name: OP/00007
product_id: mrp.product_product_buttons0
product_max_qty: 50.0
product_min_qty: 10.0
product_uom: product.product_uom_unit
qty_multiple: 1
warehouse_id: stock.warehouse0
-
I create a procurement order for product Shirt.
-
!record {model: mrp.procurement, id: mrp_procurement_shirt0}:
name: 'PROC: Shirt'
product_id: product_product_shirt0
product_qty: 5.00
location_id: stock.stock_location_stock
product_uom: product.product_uom_unit
-
I confirm the procurement order.
-
!workflow {model: mrp.procurement, action: button_confirm, ref: mrp_procurement_shirt0}
-
I run the procurement.
-
!workflow {model: mrp.procurement, action: button_check, ref: mrp_procurement_shirt0}
-
I see that there is a manufacturing order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0'))])
assert order_ids, 'No Manufacturing Order.'
-
I also check that there are two more procurement orders for sub products Cloth and Buttons.
-
!python {model: mrp.procurement}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_cloth0'),ref('product_product_buttons0')])])
assert proc_ids, 'No Procurements.'
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
search: "[]"
-
I check that there is one purchase order for Cloth.
-
!python {model: purchase.order}: |
purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')])
assert purch_ids, 'No Purchase Orders.'
-
I confirm purchase order for Cloth.
-
!python {model: purchase.order}: |
import netsvc
purch_ids = self.search(cr, uid, [('partner_id.name','=','Maxtor')])
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
-
I get the approval from the supplier. So I approve my purchase orders.
-
!python {model: purchase.order}: |
from tools.translate import _
import netsvc
purch_ids = self.search(cr, uid, [('state','=','confirmed')])
assert purch_ids, _('No Confirmed Purchase Orders found!')
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_approve', cr)
-
I confirm purchase order for Buttons.
-
!python {model: purchase.order}: |
import netsvc
purch_ids = self.search(cr, uid, [('partner_id.name','=','ASUStek')])
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_confirm', cr)
-
I get the approval from the supplier. So I approve my purchase orders.
-
!python {model: purchase.order}: |
from tools.translate import _
import netsvc
purch_ids = self.search(cr, uid, [('state','=','confirmed')])
assert purch_ids, _('No Confirmed Purchase Orders found!')
wf_service = netsvc.LocalService("workflow")
for p_id in purch_ids:
wf_service.trg_validate(uid, 'purchase.order', p_id, 'purchase_approve', cr)
-
I Check incoming shipments for cloth. And receive products.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!')
-
!record {model: stock.partial.picking, id: stock_partial_picking0}:
date: '2010-04-30 16:53:36'
partner_id: base.res_partner_maxtor
address_id: base.res_partner_address_wong
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
partial = self.browse(cr, uid, 1, context)
partial_datas = {
'partner_id' : partial.partner_id and partial.partner_id.id or False,
'address_id' : partial.address_id and partial.address_id.id or False,
'delivery_date' : partial.date
}
for pick in pick_obj.browse(cr, uid, picking_ids):
for m in pick.move_lines:
partial_datas['move%s'%(m.id)] = {
'product_id' : m.product_id.id,
'product_qty' : m.product_qty,
'product_uom' : m.product_uom.id
}
if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
partial_datas['move%s'%(m.id)].update({
'product_price' : m.product_price,
'product_currency': m.product_currency
})
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
-
I Check incoming shipments for buttons. And receive products.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!')
-
!record {model: stock.partial.picking, id: stock_partial_picking0}:
date: '2010-04-30 16:53:36'
partner_id: base.res_partner_maxtor
address_id: base.res_partner_address_wong
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
picking_ids = pick_obj.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
partial = self.browse(cr, uid, 1, context)
partial_datas = {
'partner_id': partial.partner_id and partial.partner_id.id or False,
'address_id': partial.address_id and partial.address_id.id or False,
'delivery_date': partial.date
}
for pick in pick_obj.browse(cr, uid, picking_ids):
for m in pick.move_lines:
partial_datas['move%s'%(m.id)] = {
'product_id': m.product_id.id,
'product_qty': m.product_qty,
'product_uom': m.product_uom.id
}
if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
partial_datas['move%s'%(m.id)].update({
'product_price': m.product_price,
'product_currency': m.product_currency
})
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
-
Run scheduler again.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
search: "[]"
-
Check state of manufacturing order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('product_id','=',ref('product_product_shirt0')),('state','=','ready')])
assert order_ids, 'No Manufacturing Order in Ready state.'
-
I start production order for Shirt.
-
!python {model: mrp.production}: |
from tools.translate import _
import netsvc
prod_ids = self.search(cr, uid, [('state','=','ready')])
assert prod_ids, _('No Ready Manufacturing Orders found!')
wf_service = netsvc.LocalService("workflow")
for p_id in prod_ids:
wf_service.trg_validate(uid, 'mrp.production', p_id, 'button_produce', cr)
-
!record {model: mrp.product.produce, id: mrp_product_produce0}:
product_qty: 5.00
mode: 'consume_produce'
-
!python {model: mrp.product.produce}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
-
!record {model: stock.move.consume, id: stock_move_consume0}:
product_id: product_product_buttons0
product_qty: 35.00
product_uom: product.product_uom_unit
location_id: stock.stock_location_stock
-
!python {model: stock.move.consume}: |
from tools.translate import _
stock_obj = self.pool.get('stock.move')
stock_ids = stock_obj.search(cr, uid, [('product_id.name','=','Buttons')])
self.do_move_consume(cr, uid, [1], context={'active_ids': stock_ids})
-
And finally production order is done.
-
!python {model: mrp.product.produce}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})

View File

@ -86,27 +86,27 @@
-
!python {model: mrp.procurement}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('origin','=',':MO/00004')])
proc_ids = self.search(cr, uid, [('state','!=','confirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
search: "[('origin','=',':MO/00004')]"
search: "[('state','=','confirmed')]"
-
I am checking Internal picking.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('type','=','internal')])
pick_ids = self.search(cr, uid, [('state','!=','done'),('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
I see that there is a manufacturing order for the subproduct of PC1 with ready state.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('state','=','ready')])
order_ids = self.search(cr, uid, [('state','=','confirmed')])
assert order_ids, _('No manufacturing order!')
-
I start producing that product first. So I marked it as started.
@ -117,7 +117,7 @@
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('origin','=',':MO/00004')])
prod_ids = prod_obj.search(cr, uid, [('state','=','confirmed')])
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
-
Now the manufacturing order for subproduct CPU_GEN is done. And manufacturing
@ -125,7 +125,7 @@
-
!python {model: mrp.production}: |
from tools.translate import _
prod_ids = self.search(cr, uid, [('origin','=',':MO/00004'),('state','=','done')])
prod_ids = self.search(cr, uid, [('state','!=','done')])
assert prod_ids, _('Manufacturing order is yet not done!')
-
I start producing the product PC1.

View File

@ -60,6 +60,7 @@
# 'process/sale_process.xml',
],
'demo_xml': ['sale_demo.xml'],
'test': ['test/sale_procurement.yml'],
'installable': True,
'active': False,
'certificate': '0058103601429',

View File

@ -0,0 +1,93 @@
-
In order to test the sale order working with procurements I will create some
products with different supply method and procurement method.
-
I create two products.
-
!record {model: product.product, id: product_product_table0}:
categ_id: product.cat1
name: Table
procure_method: make_to_order
supply_method: produce
type: product
uom_id: product.product_uom_unit
uom_po_id: product.product_uom_unit
-
!record {model: product.product, id: product_product_wood0}:
categ_id: product.cat1
name: Wood
procure_method: make_to_stock
supply_method: buy
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
-
I define Minimum stock rule for my stockable product wood
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}:
company_id: base.main_company
location_id: stock.stock_location_stock
logic: max
name: OP/00002
product_id: product_product_wood0
product_max_qty: 15.0
product_min_qty: 10.0
product_uom: product.product_uom_kgm
qty_multiple: 1
warehouse_id: stock.warehouse0
-
Now I make a sale order for table.
-
!record {model: sale.order, id: sale_order_so0}:
amount_total: 5.0
amount_untaxed: 5.0
date_order: '2010-04-30'
invoice_quantity: order
name: SO006
order_line:
- company_id: base.main_company
delay: 7.0
name: Table
price_unit: 1.0
product_id: product_product_table0
product_uom: product.product_uom_unit
product_uom_qty: 5.0
product_uos_qty: 5.0
state: draft
type: make_to_order
order_policy: manual
partner_id: base.res_partner_agrolait
partner_invoice_id: base.res_partner_address_8
partner_order_id: base.res_partner_address_8
partner_shipping_id: base.res_partner_address_8
picking_policy: direct
pricelist_id: product.list0
shop_id: sale.shop
-
I confirm the order.
-
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so0}
-
I check that one procurement is generated.
-
!python {model: mrp.procurement}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('state','=','confirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
search: "[('state','=','confirmed')]"
-
I check that the procurement for the product table is in exception state.
As my product's supply method is produce and mrp module is yet not installed.
-
!python {model: mrp.procurement}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('state','=','exception')])
assert proc_ids, _('No Procurements are in exception state!')