[MERGE]: merging fromdevelopment branch one

bzr revid: mga@tinyerp.com-20100420204033-0gjntda6oxdbdc5e
This commit is contained in:
Mantavya Gajjar 2010-04-21 02:10:33 +05:30
commit b7eb11fe0d
42 changed files with 1371 additions and 783 deletions

View File

@ -481,10 +481,11 @@ class auction_lots(osv.osv):
return result
def name_search(self, cr, user, name, args=None, operator='ilike', context={}):
if not args:
if not len(args):
args = []
ids = self.search(cr, user, [('obj_num','=',int(name))] + args)
ids = []
if name:
ids = self.search(cr, user, [('obj_num','=',int(name))] + args)
if not ids:
ids = self.search(cr, user, [('name',operator,name)] + args)
return self.name_get(cr, user, ids)

View File

@ -26,23 +26,23 @@ class mrp_installer(osv.osv_memory):
_columns = {
# Manufacturing Resource Planning
'stock_location':fields.boolean('Advanced Routes',
'stock_location': fields.boolean('Advanced Routes',
help="Manages product routes and paths within and between "
"locations (e.g. warehouses)"),
'mrp_jit':fields.boolean('Just In Time Scheduling',
'mrp_jit': fields.boolean('Just In Time Scheduling',
help="Enables Just In Time computation of procurement orders."
"\n\nWhile it's more resource intensive than the default "
"setup, the JIT computer avoids having to wait for the "
"procurement scheduler to run or having to run the "
"procurement scheduler manually."),
'mrp_operations':fields.boolean('Manufacturing Operations',
'mrp_operations': fields.boolean('Manufacturing Operations',
help="Enhances production orders with readiness states as well "
"as the dates of start and end of execution of the order."),
'mrp_subproduct':fields.boolean('MRP Subproducts',
'mrp_subproduct': fields.boolean('MRP Subproducts',
help="Enables multiple product output from a single production "
"order: without this, a productio order can have only one "
"output product."),
'mrp_repair':fields.boolean('Repairs',
'mrp_repair': fields.boolean('Repairs',
help="Enables warranty and repair management (and their impact "
"on stocks and invoicing)."),
}

View File

@ -161,15 +161,16 @@ class mrp_bom(osv.osv):
@return: Dictionary of values
"""
result = {}
bom_obj = self.pool.get('mrp.bom')
for bom in self.browse(cr, uid, ids, context=context):
result[bom.id] = map(lambda x: x.id, bom.bom_lines)
if bom.bom_lines:
continue
ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce'))
if bom.type=='phantom' or ok:
sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
sids = bom_obj.search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)])
if sids:
bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context)
bom2 = bom_obj.browse(cr, uid, sids[0], context=context)
result[bom.id] += map(lambda x: x.id, bom2.bom_lines)
return result
@ -182,13 +183,13 @@ class mrp_bom(osv.osv):
"""
res = dict(map(lambda x: (x,''), ids))
for line in self.browse(cr, uid, ids):
if line.type=='phantom' and not line.bom_id:
if line.type == 'phantom' and not line.bom_id:
res[line.id] = 'set'
continue
if line.bom_lines or line.type=='phantom':
if line.bom_lines or line.type == 'phantom':
continue
if line.product_id.supply_method=='produce':
if line.product_id.procure_method=='make_to_stock':
if line.product_id.supply_method == 'produce':
if line.product_id.procure_method == 'make_to_stock':
res[line.id] = 'stock'
else:
res[line.id] = 'order'
@ -223,7 +224,6 @@ class mrp_bom(osv.osv):
'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hierarchy", type='many2many'),
'company_id': fields.many2one('res.company','Company',required=True),
'multi_level_bom': fields.boolean('Multi-level BoM'),
}
_defaults = {
'active': lambda *a: 1,
@ -261,8 +261,8 @@ class mrp_bom(osv.osv):
@return: Dictionary of changed values
"""
if product_id:
prod=self.pool.get('product.product').browse(cr,uid,[product_id])[0]
v = {'product_uom':prod.uom_id.id}
prod = self.pool.get('product.product').browse(cr, uid, [product_id])[0]
v = {'product_uom': prod.uom_id.id}
if not name:
v['name'] = prod.name
return {'value': v}
@ -285,8 +285,8 @@ class mrp_bom(osv.osv):
prop = 0
for prop_id in bom.property_ids:
if prop_id.id in properties:
prop+=1
if (prop>max_prop) or ((max_prop==0) and not result):
prop += 1
if (prop > max_prop) or ((max_prop == 0) and not result):
result = bom.id
max_prop = prop
return result
@ -303,20 +303,20 @@ class mrp_bom(osv.osv):
"""
factor = factor / (bom.product_efficiency or 1.0)
factor = rounding(factor, bom.product_rounding)
if factor<bom.product_rounding:
if factor < bom.product_rounding:
factor = bom.product_rounding
result = []
result2 = []
phantom=False
if bom.type=='phantom' and not bom.bom_lines:
phantom = False
if bom.type == 'phantom' and not bom.bom_lines:
newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
if newbom:
res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10)
result = result + res[0]
result2 = result2 + res[1]
phantom=True
phantom = True
else:
phantom=False
phantom = False
if not phantom:
if addthis and not bom.bom_lines:
result.append(
@ -348,7 +348,7 @@ class mrp_bom(osv.osv):
result2 = result2 + res[1]
return result, result2
def set_indices(self, cr, uid, ids, context = {}):
def set_indices(self, cr, uid, ids, context={}):
""" Sets Indices.
@return: True
"""
@ -361,10 +361,10 @@ class mrp_bom(osv.osv):
bom_rev_obj = self.pool.get('mrp.bom.revision')
for rev_id in rev_ids:
if res[0]['revision_type'] == 'numeric':
bom_rev_obj.write(cr, uid, [rev_id], {'indice' : idx})
bom_rev_obj.write(cr, uid, [rev_id], {'indice': idx})
else:
bom_rev_obj.write(cr, uid, [rev_id], {'indice' : "%c"%(idx+96,)})
idx+=1
bom_rev_obj.write(cr, uid, [rev_id], {'indice': "%c" %(idx+96,)})
idx += 1
return True
mrp_bom()
@ -372,6 +372,7 @@ mrp_bom()
class mrp_bom_revision(osv.osv):
_name = 'mrp.bom.revision'
_description = 'Bill of material revisions'
_columns = {
'name': fields.char('Modification name', size=64, required=True),
'description': fields.text('Description'),
@ -383,7 +384,7 @@ class mrp_bom_revision(osv.osv):
}
_defaults = {
'author_id': lambda x,y,z,c: z,
'author_id': lambda x, y, z, c: z,
'date': lambda *a: time.strftime('%Y-%m-%d'),
}
@ -443,7 +444,7 @@ class mrp_production(osv.osv):
def _production_calc(self, cr, uid, ids, prop, unknow_none, context={}):
""" Calculates total hours and total no. of cycles for a production order.
@param prop:
@param prop: Name of field.
@param unknow_none:
@return: Dictionary of values.
"""
@ -541,10 +542,11 @@ class mrp_production(osv.osv):
'state': lambda *a: 'draft',
'date_planned': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'product_qty': lambda *a: 1.0,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.production') or '/',
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.production', context=c),
'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'mrp.production') or '/',
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.production', context=c),
}
_order = 'date_planned asc, priority desc';
def unlink(self, cr, uid, ids, context=None):
productions = self.read(cr, uid, ids, ['state'])
unlink_ids = []
@ -587,8 +589,8 @@ class mrp_production(osv.osv):
return {}
res = self.pool.get('product.product').read(cr, uid, [product], ['uom_id'])[0]
uom = res['uom_id'] and res['uom_id'][0]
result = {'product_uom':uom}
return {'value':result}
result = {'product_uom': uom}
return {'value': result}
def bom_id_change(self, cr, uid, ids, product):
""" Finds routing for changed BoM.
@ -599,14 +601,14 @@ class mrp_production(osv.osv):
return {}
res = self.pool.get('mrp.bom').read(cr, uid, [product], ['routing_id'])[0]
routing_id = res['routing_id'] and res['routing_id'][0]
result = {'routing_id':routing_id}
return {'value':result}
result = {'routing_id': routing_id}
return {'value': result}
def action_picking_except(self, cr, uid, ids):
""" Changes the state to Exception.
@return: True
"""
self.write(cr, uid, ids, {'state':'picking_except'})
self.write(cr, uid, ids, {'state': 'picking_except'})
return True
def action_compute(self, cr, uid, ids, properties=[]):
@ -657,7 +659,7 @@ class mrp_production(osv.osv):
if production.move_created_ids:
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
self.write(cr, uid, ids, {'state':'cancel'}) #,'move_lines':[(6,0,[])]})
self.write(cr, uid, ids, {'state': 'cancel'}) #,'move_lines':[(6,0,[])]})
return True
#XXX: may be a bug here; lot_lines are unreserved for a few seconds;
@ -667,11 +669,11 @@ class mrp_production(osv.osv):
@return: True
"""
move_obj = self.pool.get('stock.move')
self.write(cr, uid, ids, {'state':'ready'})
self.write(cr, uid, ids, {'state': 'ready'})
for production in self.browse(cr, uid, ids):
if production.move_prod_id:
move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id':production.location_dest_id.id})
{'location_id': production.location_dest_id.id})
return True
def action_production_end(self, cr, uid, ids):
@ -680,7 +682,7 @@ class mrp_production(osv.osv):
"""
for production in self.browse(cr, uid, ids):
self._costs_generate(cr, uid, production)
return self.write(cr, uid, ids, {'state': 'done', 'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
return self.write(cr, uid, ids, {'state': 'done', 'date_finnished': time.strftime('%Y-%m-%d %H:%M:%S')})
def test_production_done(self, cr, uid, ids):
""" Tests whether production is done or not.
@ -765,7 +767,7 @@ class mrp_production(osv.osv):
if final_product.id not in parent_move_ids:
new_parent_ids.append(final_product.id)
for new_parent_id in new_parent_ids:
stock_mov_obj.write(cr, uid, [raw_product.id], {'move_history_ids':[(4,new_parent_id)]})
stock_mov_obj.write(cr, uid, [raw_product.id], {'move_history_ids': [(4,new_parent_id)]})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.production', production_id, 'button_produce_done', cr)
@ -786,7 +788,7 @@ class mrp_production(osv.osv):
if value and account:
amount += value
analytic_line_obj.create(cr, uid, {
'name': wc_line.name+' (H)',
'name': wc_line.name + ' (H)',
'amount': value,
'account_id': account,
'general_account_id': wc.costs_general_account_id.id,
@ -813,7 +815,7 @@ class mrp_production(osv.osv):
@return: True
"""
move_ids = []
self.write(cr, uid, ids, {'state': 'in_production','date_start':time.strftime('%Y-%m-%d %H:%M:%S')})
self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def test_if_product(self, cr, uid, ids):
@ -834,12 +836,13 @@ class mrp_production(osv.osv):
""" Confirms production order.
@return: Newly generated picking Id.
"""
picking_id=False
picking_id = False
proc_ids = []
seq_obj = self.pool.get('ir.sequence')
pick_obj = self.pool.get('stock.picking')
move_obj = self.pool.get('stock.move')
proc_obj = self.pool.get('mrp.procurement')
wf_service = netsvc.LocalService("workflow")
for production in self.browse(cr, uid, ids):
if not production.product_lines:
self.action_compute(cr, uid, [production.id])
@ -849,14 +852,14 @@ class mrp_production(osv.osv):
address_id = False
if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
routing_loc = production.bom_id.routing_id.location_id
if routing_loc.usage<>'internal':
if routing_loc.usage <> 'internal':
pick_type = 'out'
address_id = routing_loc.address_id and routing_loc.address_id.id or False
routing_loc = routing_loc.id
pick_name = seq_obj.get(cr, uid, 'stock.picking.'+pick_type)
pick_name = seq_obj.get(cr, uid, 'stock.picking.' + pick_type)
picking_id = pick_obj.create(cr, uid, {
'name': pick_name,
'origin': (production.origin or '').split(':')[0] +':'+production.name,
'origin': (production.origin or '').split(':')[0] + ':' + production.name,
'type': pick_type,
'move_type': 'one',
'state': 'auto',
@ -867,7 +870,7 @@ class mrp_production(osv.osv):
source = production.product_id.product_tmpl_id.property_stock_production.id
data = {
'name':'PROD:'+production.name,
'name':'PROD:' + production.name,
'date_planned': production.date_planned,
'product_id': production.product_id.id,
'product_qty': production.product_qty,
@ -885,11 +888,11 @@ class mrp_production(osv.osv):
self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
moves = []
for line in production.product_lines:
move_id=False
move_id = False
newdate = production.date_planned
if line.product_id.type in ('product', 'consu'):
res_dest_id = move_obj.create(cr, uid, {
'name':'PROD:'+production.name,
'name':'PROD:' + production.name,
'date_planned': production.date_planned,
'product_id': line.product_id.id,
'product_qty': line.product_qty,
@ -904,7 +907,7 @@ class mrp_production(osv.osv):
})
moves.append(res_dest_id)
move_id = move_obj.create(cr, uid, {
'name':'PROD:'+production.name,
'name':'PROD:' + production.name,
'picking_id':picking_id,
'product_id': line.product_id.id,
'product_qty': line.product_qty,
@ -932,12 +935,10 @@ class mrp_production(osv.osv):
'move_id': move_id,
'company_id': production.company_id.id,
})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
proc_ids.append(proc_id)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
self.write(cr, uid, [production.id], {'picking_id':picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
return picking_id
def force_production(self, cr, uid, ids, *args):
@ -955,6 +956,7 @@ class mrp_production_workcenter_line(osv.osv):
_name = 'mrp.production.workcenter.line'
_description = 'Work Orders'
_order = 'sequence'
_columns = {
'name': fields.char('Work Order', size=64, required=True),
'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True),
@ -973,6 +975,7 @@ mrp_production_workcenter_line()
class mrp_production_product_line(osv.osv):
_name = 'mrp.production.product.line'
_description = 'Production scheduled products'
_columns = {
'name': fields.char('Name', size=64, required=True),
'product_id': fields.many2one('product.product', 'Product', required=True),
@ -998,6 +1001,7 @@ class mrp_procurement(osv.osv):
_name = "mrp.procurement"
_description = "Procurement"
_order = 'priority,date_planned'
_columns = {
'name': fields.char('Reason', size=64, required=True, help='Procurement name.'),
'origin': fields.char('Source Document', size=64,
@ -1038,7 +1042,7 @@ class mrp_procurement(osv.osv):
('waiting','Waiting')], 'State', required=True,
help='When a procurement is created the state is set to \'Draft\'.\n If the procurement is confirmed, the state is set to \'Confirmed\'.\
\nAfter confirming the state is set to \'Running\'.\n If any exception arises in the order then the state is set to \'Exception\'.\n Once the exception is removed the state becomes \'Ready\'.\n It is in \'Waiting\'. state when the procurement is waiting for another one to finish.'),
'note' : fields.text('Note'),
'note': fields.text('Note'),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
@ -1047,7 +1051,7 @@ class mrp_procurement(osv.osv):
'date_planned': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'close_move': lambda *a: 0,
'procure_method': lambda *a: 'make_to_order',
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.procurement', context=c)
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.procurement', context=c)
}
def unlink(self, cr, uid, ids, context=None):
@ -1066,10 +1070,10 @@ class mrp_procurement(osv.osv):
@return: Dictionary of values.
"""
if product_id:
w=self.pool.get('product.product').browse(cr,uid,product_id, context)
w = self.pool.get('product.product').browse(cr, uid, product_id, context)
v = {
'product_uom':w.uom_id.id,
'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id
'product_uom': w.uom_id.id,
'product_uos': w.uos_id and w.uos_id.id or w.uom_id.id
}
return {'value': v}
return {}
@ -1092,7 +1096,7 @@ class mrp_procurement(osv.osv):
for procurement in self.browse(cr, uid, ids, context):
if procurement.move_id:
ok = True
if not procurement.move_id.state=='cancel':
if not procurement.move_id.state == 'cancel':
res = False
return res and ok
@ -1103,7 +1107,7 @@ class mrp_procurement(osv.osv):
res = True
for proc in self.browse(cr, uid, ids, context):
if proc.move_id:
if not proc.move_id.state=='done':
if not proc.move_id.state == 'done':
res = False
return res
@ -1116,7 +1120,7 @@ class mrp_procurement(osv.osv):
@param proc: Current procurement.
@return: Quantity or False.
"""
if proc.product_id.type=='product':
if proc.product_id.type == 'product':
if proc.move_id.product_uos:
return proc.move_id.product_uos_qty
return False
@ -1126,7 +1130,7 @@ class mrp_procurement(osv.osv):
@param proc: Current procurement.
@return: UoS or False.
"""
if proc.product_id.type=='product':
if proc.product_id.type == 'product':
if proc.move_id.product_uos:
return proc.move_id.product_uos.id
return False
@ -1160,7 +1164,7 @@ class mrp_procurement(osv.osv):
@return: True or False
"""
for procurement in self.browse(cr, uid, ids, context=context):
if procurement.move_id and procurement.move_id.state=='auto':
if procurement.move_id and procurement.move_id.state == 'auto':
return True
return False
@ -1185,7 +1189,7 @@ class mrp_procurement(osv.osv):
"""
ok = True
for procurement in self.browse(cr, uid, ids, context=context):
if procurement.product_id.type=='service':
if procurement.product_id.type == 'service':
ok = ok and self._check_make_to_stock_service(cr, uid, procurement, context)
else:
ok = ok and self._check_make_to_stock_product(cr, uid, procurement, context)
@ -1198,7 +1202,7 @@ class mrp_procurement(osv.osv):
res = True
user = self.pool.get('res.users').browse(cr, uid, uid)
for procurement in self.browse(cr, uid, ids):
if procurement.product_id.product_tmpl_id.supply_method<>'produce':
if procurement.product_id.product_tmpl_id.supply_method <> 'produce':
if procurement.product_id.seller_ids:
partner = procurement.product_id.seller_ids[0].name
if user.company_id and user.company_id.partner_id:
@ -1220,7 +1224,7 @@ class mrp_procurement(osv.osv):
user = self.pool.get('res.users').browse(cr, uid, uid)
partner_obj = self.pool.get('res.partner')
for procurement in self.browse(cr, uid, ids):
if procurement.product_id.product_tmpl_id.supply_method<>'buy':
if procurement.product_id.product_tmpl_id.supply_method <> 'buy':
return False
if not procurement.product_id.seller_ids:
cr.execute('update mrp_procurement set message=%s where id=%s', (_('No supplier defined for this product !'), procurement.id))
@ -1240,7 +1244,7 @@ class mrp_procurement(osv.osv):
@return: True or False
"""
for record in self.browse(cr, uid, ids):
if record.move_id and record.move_id.state=='cancel':
if record.move_id and record.move_id.state == 'cancel':
return True
return False
@ -1255,32 +1259,32 @@ class mrp_procurement(osv.osv):
if procurement.product_id.type in ('product', 'consu'):
if not procurement.move_id:
source = procurement.location_id.id
if procurement.procure_method=='make_to_order':
if procurement.procure_method == 'make_to_order':
source = procurement.product_id.product_tmpl_id.property_stock_procurement.id
id = move_obj.create(cr, uid, {
'name': 'PROC:'+procurement.name,
'name': 'PROC:' + procurement.name,
'location_id': source,
'location_dest_id': procurement.location_id.id,
'product_id': procurement.product_id.id,
'product_qty':procurement.product_qty,
'product_qty': procurement.product_qty,
'product_uom': procurement.product_uom.id,
'date_planned': procurement.date_planned,
'state':'confirmed',
'state': 'confirmed',
'company_id': procurement.company_id.id,
})
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move':1})
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move': 1})
else:
# TODO: check this
if procurement.procure_method=='make_to_stock' and procurement.move_id.state in ('waiting',):
if procurement.procure_method == 'make_to_stock' and procurement.move_id.state in ('waiting',):
id = move_obj.write(cr, uid, [procurement.move_id.id], {'state':'confirmed'})
self.write(cr, uid, ids, {'state':'confirmed','message':''})
self.write(cr, uid, ids, {'state': 'confirmed', 'message': ''})
return True
def action_move_assigned(self, cr, uid, ids, context={}):
""" Changes procurement state to Running and writes message.
@return: True
"""
self.write(cr, uid, ids, {'state':'running','message':_('from stock: products assigned.')})
self.write(cr, uid, ids, {'state': 'running', 'message': _('from stock: products assigned.')})
return True
def _check_make_to_stock_service(self, cr, uid, procurement, context={}):
@ -1306,7 +1310,7 @@ class mrp_procurement(osv.osv):
@return: True
"""
for procurement in self.browse(cr, uid, ids):
self.write(cr, uid, [procurement.id], {'state':'running'})
self.write(cr, uid, [procurement.id], {'state': 'running'})
return True
def action_produce_assign_product(self, cr, uid, ids, context={}):
@ -1346,12 +1350,12 @@ class mrp_procurement(osv.osv):
'company_id': procurement.company_id.id,
})
res[procurement.id] = produce_id
self.write(cr, uid, [procurement.id], {'state':'running'})
self.write(cr, uid, [procurement.id], {'state': 'running'})
bom_result = production_obj.action_compute(cr, uid,
[produce_id], properties=[x.id for x in procurement.property_ids])
wf_service.trg_validate(uid, 'mrp.production', produce_id, 'button_confirm', cr)
move_obj.write(cr, uid, [res_id],
{'location_id':procurement.location_id.id})
{'location_id': procurement.location_id.id})
return res
def action_po_assign(self, cr, uid, ids, context={}):
@ -1385,7 +1389,7 @@ class mrp_procurement(osv.osv):
qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id)
if procurement.product_id.seller_ids[0].qty:
qty=max(qty,procurement.product_id.seller_ids[0].qty)
qty = max(qty,procurement.product_id.seller_ids[0].qty)
price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, False, {'uom': uom_id})[pricelist_id]
@ -1394,9 +1398,9 @@ class mrp_procurement(osv.osv):
newdate = newdate - procurement.product_id.seller_ids[0].delay
#Passing partner_id to context for purchase order line integrity of Line name
context.update({'lang':partner.lang, 'partner_id':partner_id})
context.update({'lang': partner.lang, 'partner_id': partner_id})
product = prod_obj.browse(cr,uid,procurement.product_id.id,context=context)
product = prod_obj.browse(cr, uid, procurement.product_id.id, context=context)
line = {
'name': product.partner_ref,
@ -1406,13 +1410,13 @@ class mrp_procurement(osv.osv):
'price_unit': price,
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
'move_dest_id': res_id,
'notes':product.description_purchase,
'notes': product.description_purchase,
}
taxes_ids = procurement.product_id.product_tmpl_id.supplier_taxes_id
taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
line.update({
'taxes_id':[(6,0,taxes)]
'taxes_id': [(6,0,taxes)]
})
purchase_id = po_obj.create(cr, uid, {
'origin': procurement.origin,
@ -1425,7 +1429,7 @@ class mrp_procurement(osv.osv):
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False
})
res[procurement.id] = purchase_id
self.write(cr, uid, [procurement.id], {'state':'running', 'purchase_id':purchase_id})
self.write(cr, uid, [procurement.id], {'state': 'running', 'purchase_id': purchase_id})
return res
def action_cancel(self, cr, uid, ids):
@ -1437,16 +1441,16 @@ class mrp_procurement(osv.osv):
move_obj = self.pool.get('stock.move')
for proc in self.browse(cr, uid, ids):
if proc.close_move:
if proc.move_id.state not in ('done','cancel'):
if proc.move_id.state not in ('done', 'cancel'):
todo2.append(proc.move_id.id)
else:
if proc.move_id and proc.move_id.state=='waiting':
if proc.move_id and proc.move_id.state == 'waiting':
todo.append(proc.move_id.id)
if len(todo2):
move_obj.action_cancel(cr, uid, todo2)
if len(todo):
move_obj.write(cr, uid, todo, {'state':'assigned'})
self.write(cr, uid, ids, {'state':'cancel'})
move_obj.write(cr, uid, todo, {'state': 'assigned'})
self.write(cr, uid, ids, {'state': 'cancel'})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'mrp.procurement', id, cr)
@ -1461,7 +1465,7 @@ class mrp_procurement(osv.osv):
"""
ok = False
for procurement in self.browse(cr, uid, ids):
if procurement.move_id.state=='assigned' or procurement.move_id.state=='done':
if procurement.move_id.state == 'assigned' or procurement.move_id.state == 'done':
self.action_done(cr, uid, [procurement.id])
ok = True
return ok
@ -1470,7 +1474,7 @@ class mrp_procurement(osv.osv):
""" Changes procurement state to Ready.
@return: True
"""
res = self.write(cr, uid, ids, {'state':'ready'})
res = self.write(cr, uid, ids, {'state': 'ready'})
return res
def action_done(self, cr, uid, ids):
@ -1482,7 +1486,7 @@ class mrp_procurement(osv.osv):
if procurement.move_id:
if procurement.close_move and (procurement.move_id.state <> 'done'):
move_obj.action_done(cr, uid, [procurement.move_id.id])
res = self.write(cr, uid, ids, {'state':'done', 'date_close':time.strftime('%Y-%m-%d')})
res = self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'mrp.procurement', id, cr)

View File

@ -864,6 +864,7 @@
<field name="date_planned" widget="date"/>
<field name="state" />
</group>
<newline/>
<group expand="1" string="Group By" colspan="4" col="8">
<filter string="Product" icon="terp-mrp" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="Reason" icon="terp-mrp" domain="[]" context="{'group_by':'name'}"/>

View File

@ -27,13 +27,9 @@ class product_product(osv.osv):
_inherit = "product.product"
def get_product_accounts(self, cr, uid, product_id, context={}):
"""
To get the stock input account, stock output account and stock journal related to product.
@param product_id : product id
@return: dictionary which contains information regarding stock input account, stock output account and stock journal
""" To get the stock input account, stock output account and stock journal related to product.
@param product_id: product id
@return: dictionary which contains information regarding stock input account, stock output account and stock journal
"""
product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False)
@ -55,14 +51,10 @@ class product_product(osv.osv):
return res
def do_change_standard_price(self, cr, uid, ids, datas, context={}):
"""
Changes the Standard Price of Product and parent products and creates an account move accordingly.
@param datas : dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal
@param context: A standard dictionary
@return:
""" Changes the Standard Price of Product and parent products and creates an account move accordingly.
@param datas: dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal
@param context: A standard dictionary
@return:
"""
#TODO : TO Check
res = super(product_product, self).do_change_standard_price(cr, uid, ids, datas, context=context)
@ -73,15 +65,15 @@ class product_product(osv.osv):
if bom.bom_id.bom_lines :
for bom_line in bom.bom_id.bom_lines :
prod_price = self.read(cr, uid, bom_line.product_id.id, ['standard_price'])['standard_price']
price += bom_line.product_qty * prod_price
price += bom_line.product_qty * prod_price
accounts = self.get_product_accounts(cr, uid, bom.bom_id.product_id.id , context)
accounts = self.get_product_accounts(cr, uid, bom.bom_id.product_id.id, context)
datas = {
'new_price' : price,
'stock_output_account' : accounts['stock_account_output'],
'stock_input_account' : accounts['stock_account_input'],
'stock_journal' : accounts['stock_journal']
'new_price': price,
'stock_output_account': accounts['stock_account_output'],
'stock_input_account': accounts['stock_account_input'],
'stock_journal': accounts['stock_journal']
}
super(product_product, self).do_change_standard_price(cr, uid, [bom.bom_id.product_id.id], datas, context)
_compute_price(bom.bom_id)

View File

@ -60,7 +60,7 @@ class mrp_procurement(osv.osv):
cr.execute('select id from mrp_procurement where state=%s and procure_method=%s order by priority,date_planned limit 500 offset %s', ('confirmed', 'make_to_order', offset))
ids = map(lambda x: x[0], cr.fetchall())
for proc in procurement_obj.browse(cr, uid, ids):
if (maxdate.strftime('%Y-%m-%d')>=proc.date_planned):
if (maxdate.strftime('%Y-%m-%d') >= proc.date_planned):
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
else:
offset += 1
@ -81,7 +81,7 @@ class mrp_procurement(osv.osv):
ids = []
while True:
report_ids = []
ids = self.pool.get('mrp.procurement').search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
for proc in procurement_obj.browse(cr, uid, ids):
if ((maxdate).strftime('%Y-%m-%d') >= proc.date_planned) :
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
@ -140,7 +140,7 @@ class mrp_procurement(osv.osv):
for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context):
context['warehouse'] = warehouse
for product in self.pool.get('product.product').browse(cr, uid, products_id, context=context):
for product in product_obj.browse(cr, uid, products_id, context=context):
if product.virtual_available >= 0.0:
continue

View File

@ -34,6 +34,7 @@ class stock_warehouse_orderpoint(osv.osv):
"""
_name = "stock.warehouse.orderpoint"
_description = "Orderpoint minimum rule"
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."),
@ -59,28 +60,31 @@ class stock_warehouse_orderpoint(osv.osv):
'qty_multiple': lambda *a: 1,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '',
'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c)
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c)
}
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
""" Finds location id for changed warehouse.
@param warehouse_id: Changed id of warehouse.
@return: Dictionary of values.
"""
if warehouse_id:
w=self.pool.get('stock.warehouse').browse(cr,uid,warehouse_id, context)
v = {'location_id':w.lot_stock_id.id}
w = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context)
v = {'location_id': w.lot_stock_id.id}
return {'value': v}
return {}
def onchange_product_id(self, cr, uid, ids, product_id, context={}):
""" Finds UoM for changed product.
@param product_id: Changed id of product.
@return: Dictionary of values.
"""
if product_id:
prod=self.pool.get('product.product').browse(cr,uid,product_id)
v = {'product_uom':prod.uom_id.id}
prod = self.pool.get('product.product').browse(cr,uid,product_id)
v = {'product_uom': prod.uom_id.id}
return {'value': v}
return {}
def copy(self, cr, uid, id, default=None,context={}):
if not default:
default = {}
@ -88,14 +92,17 @@ class stock_warehouse_orderpoint(osv.osv):
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '',
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context)
stock_warehouse_orderpoint()
class StockMove(osv.osv):
_inherit = 'stock.move'
_columns = {
'production_id': fields.many2one('mrp.production', 'Production', select=True),
'procurements': fields.one2many('mrp.procurement', 'move_id', 'Procurements'),
}
def copy(self, cr, uid, id, default=None, context=None):
default = default or {}
default['procurements'] = []
@ -106,19 +113,24 @@ class StockMove(osv.osv):
@param move: Stock moves
@return: True
"""
if move.product_id.supply_method=='produce' and move.product_id.procure_method=='make_to_order':
bis = self.pool.get('mrp.bom').search(cr, uid, [
bom_obj = self.pool.get('mrp.bom')
move_obj = self.pool.get('stock.move')
procurement_obj = self.pool.get('mrp.procurement')
product_obj = self.pool.get('product.product')
wf_service = netsvc.LocalService("workflow")
if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order':
bis = bom_obj.search(cr, uid, [
('product_id','=',move.product_id.id),
('bom_id','=',False),
('type','=','phantom')])
if bis:
factor = move.product_qty
bom_point = self.pool.get('mrp.bom').browse(cr, uid, bis[0])
res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor, [])
bom_point = bom_obj.browse(cr, uid, bis[0])
res = bom_obj._bom_explode(cr, uid, bom_point, factor, [])
dest = move.product_id.product_tmpl_id.property_stock_production.id
state = 'confirmed'
if move.state=='assigned':
state='assigned'
if move.state == 'assigned':
state = 'assigned'
for line in res[0]:
valdef = {
'picking_id': move.picking_id.id,
@ -135,9 +147,9 @@ class StockMove(osv.osv):
'move_history_ids2': [(6,0,[])],
'procurements': [],
}
mid = self.pool.get('stock.move').copy(cr, uid, move.id, default=valdef)
prodobj = self.pool.get('product.product').browse(cr, uid, line['product_id'], context=context)
proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
mid = move_obj.copy(cr, uid, move.id, default=valdef)
prodobj = product_obj.browse(cr, uid, line['product_id'], context=context)
proc_id = procurement_obj.create(cr, uid, {
'name': (move.picking_id.origin or ''),
'origin': (move.picking_id.origin or ''),
'date_planned': move.date_planned,
@ -151,21 +163,18 @@ class StockMove(osv.osv):
'move_id': mid,
'company_id': line['company_id'],
})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
self.pool.get('stock.move').write(cr, uid, [move.id], {
move_obj.write(cr, uid, [move.id], {
'location_id': move.location_dest_id.id,
'auto_validate': True,
'picking_id': False,
'location_id': dest,
'state': 'waiting'
})
for m in self.pool.get('mrp.procurement').search(cr, uid, [('move_id','=',move.id)], context):
wf_service = netsvc.LocalService("workflow")
for m in procurement_obj.search(cr, uid, [('move_id','=',move.id)], context):
wf_service.trg_validate(uid, 'mrp.procurement', m, 'button_wait_done', cr)
return True
def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None):
""" Consumed product with specific quatity from specific source location.
@param product_qty: Consumed product quantity
@ -232,8 +241,9 @@ class StockPicking(osv.osv):
@param *args: Arguments
@return: Picking ids.
"""
for move in self.pool.get('stock.move').browse(cr, uid, picks):
self.pool.get('stock.move')._action_explode(cr, uid, move)
move_obj = self.pool.get('stock.move')
for move in move_obj.browse(cr, uid, picks):
move_obj._action_explode(cr, uid, move)
return picks
StockPicking()
@ -241,6 +251,7 @@ StockPicking()
class spilt_in_production_lot(osv.osv_memory):
_inherit = "stock.move.split"
def split(self, cr, uid, ids, move_ids, context=None):
""" Splits move lines into given quantities.
@param move_ids: Stock moves.
@ -255,5 +266,6 @@ class spilt_in_production_lot(osv.osv_memory):
for new_move in new_moves:
production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
return res
spilt_in_production_lot()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -187,7 +187,17 @@ class mrp_production(osv.osv):
for workcenter_line in obj.workcenter_lines:
tmp=self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id])
return super(mrp_production,self).action_production_end(cr,uid,ids)
def action_in_production(self, cr, uid, ids):
""" Changes state to In Production and writes starting date.
@return: True
"""
obj = self.browse(cr, uid, ids)[0]
workcenter_line_obj = self.pool.get('mrp.production.workcenter.line')
for workcenter_line in obj.workcenter_lines:
workcenter_line_obj.action_start_working(cr, uid, [workcenter_line.id])
return super(mrp_production,self).action_in_production(cr, uid, ids)
def action_cancel(self, cr, uid, ids):
obj=self.browse(cr,uid,ids)[0]
for workcenter_line in obj.workcenter_lines:

View File

@ -33,8 +33,18 @@ class mrp_repair(osv.osv):
_description = 'Repairs Order'
def _amount_untaxed(self, cr, uid, ids, field_name, arg, context):
""" Calculates untaxed amount.
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param uid: The current user ID for security checks
@param ids: List of selected IDs
@param field_name: Name of field.
@param arg: Argument
@param context: A standard dictionary for contextual values
@return: Dictionary of values.
"""
res = {}
cur_obj=self.pool.get('res.currency')
cur_obj = self.pool.get('res.currency')
for repair in self.browse(cr, uid, ids):
res[repair.id] = 0.0
for line in repair.operations:
@ -46,35 +56,46 @@ class mrp_repair(osv.osv):
return res
def _amount_tax(self, cr, uid, ids, field_name, arg, context):
""" Calculates taxed amount.
@param field_name: Name of field.
@param arg: Argument
@return: Dictionary of values.
"""
res = {}
cur_obj=self.pool.get('res.currency')
cur_obj = self.pool.get('res.currency')
tax_obj = self.pool.get('account.tax')
for repair in self.browse(cr, uid, ids):
val = 0.0
cur=repair.pricelist_id.currency_id
cur = repair.pricelist_id.currency_id
for line in repair.operations:
if line.to_invoice:
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id):
val+= c['amount']
for c in tax_obj.compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id):
val += c['amount']
for line in repair.fees_lines:
if line.to_invoice:
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id):
val+= c['amount']
res[repair.id]=cur_obj.round(cr, uid, cur, val)
for c in tax_obj.compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id):
val += c['amount']
res[repair.id] = cur_obj.round(cr, uid, cur, val)
return res
def _amount_total(self, cr, uid, ids, field_name, arg, context):
""" Calculates total amount.
@param field_name: Name of field.
@param arg: Argument
@return: Dictionary of values.
"""
res = {}
untax = self._amount_untaxed(cr, uid, ids, field_name, arg, context)
tax = self._amount_tax(cr, uid, ids, field_name, arg, context)
cur_obj=self.pool.get('res.currency')
cur_obj = self.pool.get('res.currency')
for id in ids:
repair=self.browse(cr, uid, [id])[0]
cur=repair.pricelist_id.currency_id
repair = self.browse(cr, uid, [id])[0]
cur = repair.pricelist_id.currency_id
res[id] = cur_obj.round(cr, uid, cur, untax.get(id, 0.0) + tax.get(id, 0.0))
return res
_columns = {
'name' : fields.char('Repair Reference',size=24, required=True),
'name': fields.char('Repair Reference',size=24, required=True),
'product_id': fields.many2one('product.product', string='Product to Repair', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'partner_id' : fields.many2one('res.partner', 'Partner', select=True, help='This field allow you to choose the parner that will be invoiced and delivered'),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', domain="[('partner_id','=',partner_id)]"),
@ -110,12 +131,12 @@ class mrp_repair(osv.osv):
select=True, required=True, states={'draft':[('readonly',False)]}, readonly=True, help='This field allow you to change the workflow of the repair order. If value selected is different from \'No Invoice\', it also allow you to select the pricelist and invoicing address.'),
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
'picking_id': fields.many2one('stock.picking', 'Picking',readonly=True),
'fees_lines' : fields.one2many('mrp.repair.fee', 'repair_id', 'Fees Lines', readonly=True, states={'draft':[('readonly',False)]}),
'internal_notes' : fields.text('Internal Notes'),
'quotation_notes' : fields.text('Quotation Notes'),
'fees_lines': fields.one2many('mrp.repair.fee', 'repair_id', 'Fees Lines', readonly=True, states={'draft':[('readonly',False)]}),
'internal_notes': fields.text('Internal Notes'),
'quotation_notes': fields.text('Quotation Notes'),
'deliver_bool': fields.boolean('Deliver', help="Check this box if you want to manage the delivery once the product is repaired. If cheked, it will create a picking with selected product. Note that you can select the locations in the Info tab, if you have the extended view."),
'invoiced': fields.boolean('Invoiced', readonly=True),
'repaired' : fields.boolean('Repaired', readonly=True),
'repaired': fields.boolean('Repaired', readonly=True),
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
'amount_total': fields.function(_amount_total, method=True, string='Total'),
@ -144,6 +165,10 @@ class mrp_repair(osv.osv):
def onchange_product_id(self, cr, uid, ids, product_id=None):
""" On change of product sets some values.
@param product_id: Changed product
@return: Dictionary of values.
"""
return {'value': {
'prodlot_id': False,
'move_id': False,
@ -154,6 +179,12 @@ class mrp_repair(osv.osv):
}
def onchange_move_id(self, cr, uid, ids, prod_id=False, move_id=False):
""" On change of move id sets values of guarantee limit, source location,
destination location, partner and partner address.
@param prod_id: Id of product in current record.
@param move_id: Changed move.
@return: Dictionary of values.
"""
data = {}
data['value'] = {}
if not prod_id:
@ -179,15 +210,23 @@ class mrp_repair(osv.osv):
return True
def onchange_partner_id(self, cr, uid, ids, part, address_id):
""" On change of partner sets the values of partner address,
partner invoice address and pricelist.
@param part: Changed id of partner.
@param address_id: Address id from current record.
@return: Dictionary of values.
"""
part_obj = self.pool.get('res.partner')
pricelist_obj = self.pool.get('product.pricelist')
if not part:
return {'value': {
'address_id': False,
'partner_invoice_id': False,
'pricelist_id': self.pool.get('product.pricelist').search(cr,uid,[('type','=','sale')])[0]
'pricelist_id': pricelist_obj.search(cr, uid, [('type','=','sale')])[0]
}
}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['delivery', 'invoice', 'default'])
partner = self.pool.get('res.partner').browse(cr, uid, part)
addr = part_obj.address_get(cr, uid, [part], ['delivery', 'invoice', 'default'])
partner = part_obj.browse(cr, uid, part)
pricelist = partner.property_product_pricelist and partner.property_product_pricelist.id or False
return {'value': {
'address_id': address_id or addr['delivery'],
@ -197,6 +236,14 @@ class mrp_repair(osv.osv):
}
def onchange_lot_id(self, cr, uid, ids, lot, product_id):
""" On change of production lot sets the values of source location,
destination location, move and guarantee limit.
@param lot: Changed id of production lot.
@param product_id: Product id from current record.
@return: Dictionary of values.
"""
prodlot_obj = self.pool.get('stock.production.lot')
move_obj = self.pool.get('stock.move')
data = {}
data['value'] = {
'location_id': False,
@ -207,8 +254,8 @@ class mrp_repair(osv.osv):
if not lot:
return data
lot_info = self.pool.get('stock.production.lot').browse(cr, uid, lot)
move_ids = self.pool.get('stock.move').search(cr, uid, [('prodlot_id', '=', lot)])
lot_info = prodlot_obj.browse(cr, uid, lot)
move_ids = move_obj.search(cr, uid, [('prodlot_id', '=', lot)])
if not len(move_ids):
return data
@ -219,13 +266,17 @@ class mrp_repair(osv.osv):
return lst_move
move_id = move_ids[0]
move = get_last_move(self.pool.get('stock.move').browse(cr, uid, move_id))
move = get_last_move(move_obj.browse(cr, uid, move_id))
data['value']['move_id'] = move.id
d = self.onchange_move_id(cr, uid, ids, product_id, move.id)
data['value'].update(d['value'])
return data
def action_cancel_draft(self, cr, uid, ids, *args):
""" Cancels repair order when it is in 'Draft' state.
@param *arg: Arguments
@return: True
"""
if not len(ids):
return False
mrp_line_obj = self.pool.get('mrp.repair.line')
@ -238,6 +289,11 @@ class mrp_repair(osv.osv):
return True
def action_confirm(self, cr, uid, ids, *args):
""" Repair order state is set to 'To be invoiced' when invoice method
is 'Before repair' else state becomes 'Confirmed'.
@param *arg: Arguments
@return: True
"""
mrp_line_obj = self.pool.get('mrp.repair.line')
for o in self.browse(cr, uid, ids):
if (o.invoice_method == 'b4repair'):
@ -248,6 +304,9 @@ class mrp_repair(osv.osv):
return True
def action_cancel(self, cr, uid, ids, context=None):
""" Cancels repair order.
@return: True
"""
ok=True
mrp_line_obj = self.pool.get('mrp.repair.line')
for repair in self.browse(cr, uid, ids):
@ -259,25 +318,33 @@ class mrp_repair(osv.osv):
return self.action_invoice_create(cr, uid, ids)
def action_invoice_create(self, cr, uid, ids, group=False, context=None):
res={}
""" Creates invoice(s) for repair order.
@param group: It is set to true when group invoice is to be generated.
@return: Invoice Ids.
"""
res = {}
invoices_group = {}
inv_line_obj = self.pool.get('account.invoice.line')
inv_obj = self.pool.get('account.invoice')
repair_line_obj = self.pool.get('mrp.repair.line')
repair_fee_obj = self.pool.get('mrp.repair.fee')
for repair in self.browse(cr, uid, ids, context=context):
res[repair.id]=False
res[repair.id] = False
if repair.state in ('draft','cancel') or repair.invoice_id:
continue
if not (repair.partner_id.id and repair.partner_invoice_id.id):
raise osv.except_osv(_('No partner !'),_('You have to select a Partner Invoice Address in the repair form !'))
comment=repair.quotation_notes
comment = repair.quotation_notes
if (repair.invoice_method != 'none'):
if group and repair.partner_invoice_id.id in invoices_group:
inv_id= invoices_group[repair.partner_invoice_id.id]
invoice=invoice_obj.browse(cr, uid,inv_id)
inv_id = invoices_group[repair.partner_invoice_id.id]
invoice = inv_obj.browse(cr, uid, inv_id)
invoice_vals = {
'name': invoice.name +', '+repair.name,
'origin': invoice.origin+', '+repair.name,
'comment':(comment and (invoice.comment and invoice.comment+"\n"+comment or comment)) or (invoice.comment and invoice.comment or ''),
}
invoice_obj.write(cr, uid, [inv_id],invoice_vals,context=context)
invoice_obj.write(cr, uid, [inv_id], invoice_vals, context=context)
else:
a = repair.partner_id.property_account_receivable.id
inv = {
@ -291,10 +358,9 @@ class mrp_repair(osv.osv):
'comment': repair.quotation_notes,
'fiscal_position': repair.partner_id.property_account_position.id
}
inv_obj = self.pool.get('account.invoice')
inv_id = inv_obj.create(cr, uid, inv)
invoices_group[repair.partner_invoice_id.id] = inv_id
self.write(cr, uid, repair.id , {'invoiced':True,'invoice_id' : inv_id})
self.write(cr, uid, repair.id, {'invoiced': True, 'invoice_id': inv_id})
for operation in repair.operations:
if operation.to_invoice == True:
@ -302,29 +368,29 @@ class mrp_repair(osv.osv):
name = repair.name + '-' + operation.name
else:
name = operation.name
invoice_line_id=self.pool.get('account.invoice.line').create(cr, uid, {
invoice_line_id = inv_line_obj.create(cr, uid, {
'invoice_id': inv_id,
'name': name,
'origin':repair.name,
'origin': repair.name,
'account_id': operation.product_id and operation.product_id.property_account_income and operation.product_id.property_account_income.id,
'quantity' : operation.product_uom_qty,
'quantity': operation.product_uom_qty,
'invoice_line_tax_id': [(6,0,[x.id for x in operation.tax_id])],
'uos_id' : operation.product_uom.id,
'price_unit' : operation.price_unit,
'price_subtotal' : operation.product_uom_qty*operation.price_unit,
'product_id' : operation.product_id and operation.product_id.id or False
'uos_id': operation.product_uom.id,
'price_unit': operation.price_unit,
'price_subtotal': operation.product_uom_qty*operation.price_unit,
'product_id': operation.product_id and operation.product_id.id or False
})
self.pool.get('mrp.repair.line').write(cr, uid, [operation.id], {'invoiced':True,'invoice_line_id':invoice_line_id})
repair_line_obj.write(cr, uid, [operation.id], {'invoiced': True, 'invoice_line_id': invoice_line_id})
for fee in repair.fees_lines:
if fee.to_invoice == True:
if group:
name = repair.name + '-' + fee.name
else:
name = fee.name
invoice_fee_id=self.pool.get('account.invoice.line').create(cr, uid, {
invoice_fee_id = inv_line_obj.create(cr, uid, {
'invoice_id': inv_id,
'name': name,
'origin':repair.name,
'origin': repair.name,
'account_id': a,
'quantity': fee.product_uom_qty,
'invoice_line_tax_id': [(6,0,[x.id for x in fee.tax_id])],
@ -333,27 +399,39 @@ class mrp_repair(osv.osv):
'price_unit': fee.price_unit,
'price_subtotal': fee.product_uom_qty*fee.price_unit
})
self.pool.get('mrp.repair.fee').write(cr, uid, [fee.id], {'invoiced':True,'invoice_line_id':invoice_fee_id})
res[repair.id]=inv_id
repair_fee_obj.write(cr, uid, [fee.id], {'invoiced': True, 'invoice_line_id': invoice_fee_id})
res[repair.id] = inv_id
#self.action_invoice_end(cr, uid, ids)
return res
def action_repair_ready(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'ready'})
""" Writes repair order state to 'Ready'
@return: True
"""
self.write(cr, uid, ids, {'state': 'ready'})
return True
def action_invoice_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'invoice_except'})
""" Writes repair order state to 'Exception in invoice'
@return: True
"""
self.write(cr, uid, ids, {'state': 'invoice_except'})
return True
def action_repair_start(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'under_repair'})
""" Writes repair order state to 'Under Repair'
@return: True
"""
self.write(cr, uid, ids, {'state': 'under_repair'})
return True
def action_invoice_end(self, cr, uid, ids, context=None):
""" Writes repair order state to 'Ready' if invoice method is Before repair.
@return: True
"""
for order in self.browse(cr, uid, ids):
val = {}
if (order.invoice_method=='b4repair'):
if (order.invoice_method == 'b4repair'):
val['state'] = 'ready'
else:
#val['state'] = 'done'
@ -362,9 +440,13 @@ class mrp_repair(osv.osv):
return True
def action_repair_end(self, cr, uid, ids, context=None):
""" Writes repair order state to 'To be invoiced' if invoice method is
After repair else state is set to 'Ready'.
@return: True
"""
for order in self.browse(cr, uid, ids):
val = {}
val['repaired']=True
val['repaired'] = True
if (not order.invoiced and order.invoice_method=='after_repair'):
val['state'] = '2binvoiced'
elif (not order.invoiced and order.invoice_method=='b4repair'):
@ -376,15 +458,23 @@ class mrp_repair(osv.osv):
return True
def wkf_repair_done(self, cr, uid, ids, *args):
res=self.action_repair_done(cr,uid,ids)
res = self.action_repair_done(cr, uid, ids)
return True
def action_repair_done(self, cr, uid, ids, context=None):
""" Creates stock move and picking for repair order.
@return: Picking ids.
"""
res = {}
move_obj = self.pool.get('stock.move')
wf_service = netsvc.LocalService("workflow")
repair_line_obj = self.pool.get('mrp.repair.line')
seq_obj = self.pool.get('ir.sequence')
pick_obj = self.pool.get('stock.picking')
company = self.pool.get('res.users').browse(cr, uid, uid).company_id
for repair in self.browse(cr, uid, ids, context=context):
for move in repair.operations:
move_id = self.pool.get('stock.move').create(cr, uid, {
move_id = move_obj.create(cr, uid, {
'name': move.name,
'product_id': move.product_id.id,
'product_qty': move.product_uom_qty,
@ -395,11 +485,11 @@ class mrp_repair(osv.osv):
'tracking_id': False,
'state': 'done',
})
self.pool.get('mrp.repair.line').write(cr, uid, [move.id], {'move_id': move_id})
repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id})
if repair.deliver_bool:
pick_name = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out')
picking = self.pool.get('stock.picking').create(cr, uid, {
pick_name = seq_obj.get(cr, uid, 'stock.picking.out')
picking = pick_obj.create(cr, uid, {
'name': pick_name,
'origin': repair.name,
'state': 'draft',
@ -409,10 +499,9 @@ class mrp_repair(osv.osv):
'invoice_state': 'none',
'type': 'out',
})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', picking, 'button_confirm', cr)
move_id = self.pool.get('stock.move').create(cr, uid, {
move_id = move_obj.create(cr, uid, {
'name': repair.name,
'picking_id': picking,
'product_id': repair.product_id.id,
@ -427,10 +516,10 @@ class mrp_repair(osv.osv):
'tracking_id': False,
'state': 'assigned', # FIXME done ?
})
self.write(cr, uid, [repair.id], {'state':'done', 'picking_id':picking})
self.write(cr, uid, [repair.id], {'state': 'done', 'picking_id': picking})
res[repair.id] = picking
else:
self.write(cr, uid, [repair.id], {'state':'done'})
self.write(cr, uid, [repair.id], {'state': 'done'})
return res
@ -438,7 +527,18 @@ mrp_repair()
class ProductChangeMixin(object):
def product_id_change(self, cr, uid, ids, pricelist, product, uom=False, product_uom_qty=0, partner_id=False, guarantee_limit=False):
def product_id_change(self, cr, uid, ids, pricelist, product, uom=False,
product_uom_qty=0, partner_id=False, guarantee_limit=False):
""" On change of product it sets product quantity, tax account, name,
uom of product, unit price and price subtotal.
@param pricelist: Pricelist of current record.
@param product: Changed id of product.
@param uom: UoM of current record.
@param product_uom_qty: Quantity of current record.
@param partner_id: Partner of current record.
@param guarantee_limit: Guarantee limit of current record.
@return: Dictionary of values and warning message.
"""
result = {}
warning = {}
@ -447,7 +547,7 @@ class ProductChangeMixin(object):
result['product_uom_qty'] = product_uom_qty
if product:
product_obj = self.pool.get('product.product').browse(cr, uid, product)
product_obj = self.pool.get('product.product').browse(cr, uid, product)
if partner_id:
partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, partner.property_account_position, product_obj.taxes_id)
@ -455,7 +555,7 @@ class ProductChangeMixin(object):
result['name'] = product_obj.partner_ref
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False
if not pricelist:
warning={
warning = {
'title':'No Pricelist !',
'message':
'You have to select a pricelist in the Repair form !\n'
@ -466,14 +566,14 @@ class ProductChangeMixin(object):
product, product_uom_qty, partner_id, {'uom': uom,})[pricelist]
if price is False:
warning={
warning = {
'title':'No valid pricelist line found !',
'message':
"Couldn't find a pricelist line matching this product and quantity.\n"
"You have to change either the product, the quantity or the pricelist."
}
else:
result.update({'price_unit': price, 'price_subtotal' :price*product_uom_qty})
result.update({'price_unit': price, 'price_subtotal': price*product_uom_qty})
return {'value': result, 'warning': warning}
@ -484,10 +584,15 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
def copy_data(self, cr, uid, id, default=None, context=None):
if not default: default = {}
default.update( {'invoice_line_id':False,'move_id':False,'invoiced':False,'state':'draft'})
default.update( {'invoice_line_id': False, 'move_id': False, 'invoiced': False, 'state': 'draft'})
return super(mrp_repair_line, self).copy_data(cr, uid, id, default, context)
def _amount_line(self, cr, uid, ids, field_name, arg, context):
""" Calculates amount.
@param field_name: Name of field.
@param arg: Argument
@return: Dictionary of values.
"""
res = {}
cur_obj=self.pool.get('res.currency')
for line in self.browse(cr, uid, ids):
@ -524,10 +629,16 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
}
_defaults = {
'state': lambda *a: 'draft',
'product_uom_qty':lambda *a:1,
'product_uom_qty': lambda *a: 1,
}
def onchange_operation_type(self, cr, uid, ids, type, guarantee_limit):
""" On change of operation type it sets source location, destination location
and to invoice field.
@param product: Changed operation type.
@param guarantee_limit: Guarantee limit of current record.
@return: Dictionary of values.
"""
if not type:
return {'value': {
'location_id': False,
@ -537,19 +648,19 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
produc_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Production')])[0]
if type == 'add':
stock_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0]
to_invoice=False
to_invoice = False
if guarantee_limit and today() > mx.DateTime.strptime(guarantee_limit, '%Y-%m-%d'):
to_invoice=True
return {'value': {
'to_invoice': to_invoice,
'location_id': stock_id,
'location_dest_id' : produc_id
'location_dest_id': produc_id
}
}
return {'value': {
'to_invoice': False,
'location_id': produc_id,
'location_dest_id':False
'location_dest_id': False
}
}
@ -558,13 +669,20 @@ mrp_repair_line()
class mrp_repair_fee(osv.osv, ProductChangeMixin):
_name = 'mrp.repair.fee'
_description = 'Repair Fees line'
def copy_data(self, cr, uid, id, default=None, context=None):
if not default: default = {}
default.update( {'invoice_line_id':False,'invoiced':False})
default.update({'invoice_line_id': False, 'invoiced': False})
return super(mrp_repair_fee, self).copy_data(cr, uid, id, default, context)
def _amount_line(self, cr, uid, ids, field_name, arg, context):
""" Calculates amount.
@param field_name: Name of field.
@param arg: Argument
@return: Dictionary of values.
"""
res = {}
cur_obj=self.pool.get('res.currency')
cur_obj = self.pool.get('res.currency')
for line in self.browse(cr, uid, ids):
res[line.id] = line.to_invoice and line.price_unit * line.product_uom_qty or 0
cur = line.repair_id.pricelist_id.currency_id

View File

@ -28,17 +28,13 @@ class repair_cancel(osv.osv_memory):
_description = 'Cancel Repair'
def cancel_repair(self, cr, uid, ids, context):
"""
Cancels the repair
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
""" Cancels the repair
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
"""
record_id = context and context.get('active_id', False) or False
assert record_id, _('Active ID is not Found')
@ -54,16 +50,12 @@ class repair_cancel(osv.osv_memory):
return {}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
"""
Changes the view dynamically
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return: New arch of view.
""" Changes the view dynamically
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return: New arch of view.
"""
record_id = context and context.get('active_id', False) or False
res = super(repair_cancel, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)

View File

@ -31,21 +31,18 @@ class make_invoice(osv.osv_memory):
}
def make_invoices(self, cr, uid, ids, context):
"""
Generates invoice(s) of selected records.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return: Loads the view of new invoice(s).
""" Generates invoice(s) of selected records.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return: Loads the view of new invoice(s).
"""
inv = self.browse(cr, uid, ids[0])
order_obj = self.pool.get('mrp.repair')
newinv = order_obj.action_invoice_create(cr, uid, context['active_ids'], group=inv.group,context=context)
newinv = order_obj.action_invoice_create(cr, uid, context['active_ids'],
group=inv.group,context=context)
return {
'domain': [('id','in', newinv.values())],

View File

@ -28,6 +28,7 @@ from tools.translate import _
class account_journal(osv.osv):
_inherit = 'account.journal'
_columns = {
'auto_cash': fields.boolean('Automatic Opening', help="This field authorize the automatic creation of the cashbox"),
@ -44,21 +45,30 @@ account_journal()
class singer_statement(osv.osv):
""" Singer Statements """
_name = 'singer.statement'
_description = 'Statements'
def _sub_total(self, cr, uid, ids, name, arg, context=None):
""" Calculates Sub total"
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res = {}
for obj in self.browse(cr, uid, ids):
res[obj.id] = obj.pieces * obj.number
return res
def on_change_sub2(self, cr, uid, ids, pieces, number, *a):
sub=pieces*number
return {'value':{'subtotal': sub or 0.0}}
def on_change_sub(self, cr, uid, ids, pieces, number,*a):
""" Calculates Sub total on change of number
@param pieces: Names of fields.
@param number:
"""
sub=pieces*number
return {'value':{'subtotal': sub or 0.0}}
@ -73,8 +83,16 @@ class singer_statement(osv.osv):
singer_statement()
class account_bank_statement(osv.osv):
_inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, name, arg, context=None):
""" Find starting balance "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res ={}
for statement in self.browse(cr, uid, ids):
amount_total=0.0
@ -84,6 +102,12 @@ class account_bank_statement(osv.osv):
return res
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
""" Find encoding total of statements "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res2={}
for statement in self.browse(cr, uid, ids):
encoding_total=0.0
@ -93,8 +117,12 @@ class account_bank_statement(osv.osv):
return res2
def _default_journal_id(self, cr, uid, context={}):
""" To get default journal for the object"
@param name: Names of fields.
@return: journal
"""
company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
print [('type','=','cash'),('auto_cash','=',False), ('company_id', '=', company_id)]
journal = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash'), ('auto_cash','=',False), ('company_id', '=', company_id)])
if journal:
return journal[0]
@ -140,6 +168,12 @@ class account_bank_statement(osv.osv):
return res
def onchange_journal_id(self, cursor, user, statement_id, journal_id, context=None):
""" Changes balance start and starting details if journal_id changes"
@param statement_id: Changed statement_id
@param journal_id: Changed journal_id
@return: Dictionary of changed values
"""
id_s=[]
if not journal_id:
return {'value': {'balance_start': 0.0}}
@ -171,6 +205,10 @@ class account_bank_statement(osv.osv):
return {'value': {'balance_start': balance_start, 'starting_details_ids':new}}
def button_open(self, cr, uid, ids, context=None):
""" Changes statement state to Running.
@return: True
"""
obj_inv = self.browse(cr, uid, ids)[0]
s_id=obj_inv.journal_id
if s_id.statement_sequence_id:
@ -184,6 +222,10 @@ class account_bank_statement(osv.osv):
return True
def button_confirm(self, cr, uid, ids, context=None):
""" Check the starting and ending detail of statement
@return: True
"""
val = 0.0
val2 = 0.0
val_statement_line = 0.0

View File

@ -31,8 +31,11 @@ import re
class pos_config_journal(osv.osv):
""" Point of Sale journal configuration"""
_name = 'pos.config.journal'
_description = "Point of Sale journal configuration."
_description = "Point of Sale journal configuration"
_columns = {
'name': fields.char('Description', size=64),
'code': fields.char('Code', size=64),
@ -42,8 +45,12 @@ class pos_config_journal(osv.osv):
pos_config_journal()
class res_mode_contact(osv.osv):
""" Contact mode for Partner """
_name = "res.mode.contact"
_description = "Contact mode"
_columns={
'name': fields.char('Mode', size=64, select=1),
'active': fields.boolean('Active', select=2),
@ -51,6 +58,8 @@ class res_mode_contact(osv.osv):
res_mode_contact()
class contact_mode_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'contact_mode_id': fields.many2one('res.mode.contact','Contact Mode'),
@ -59,6 +68,9 @@ contact_mode_partner()
class pos_company_discount(osv.osv):
""" Company Discount and Cashboxes """
_inherit = 'res.company'
_columns = {
'company_discount': fields.float('Max Discount(%)', digits=(16,2)),
@ -71,12 +83,18 @@ pos_company_discount()
class pos_order(osv.osv):
""" Point of sale gives business owners a convenient way of checking out customers
and of recording sales """
_name = "pos.order"
_description = "Point of Sale"
_order = "date_order, create_date desc"
_order = "date_order desc"
def unlink(self, cr, uid, ids, context={}):
for rec in self.browse(cr, uid, ids, context=context):
for rec_statement in rec.statement_ids:
if (rec_statement.statement_id and rec_statement.statement_id.state=='confirm') or rec.state=='done':
@ -84,12 +102,20 @@ class pos_order(osv.osv):
return super(pos_order, self).unlink(cr, uid, ids, context=context)
def onchange_partner_pricelist(self, cr, uid, ids, part, context={}):
""" Changed price list on_change of partner_id"""
if not part:
return {}
pricelist = self.pool.get('res.partner').browse(cr, uid, part).property_product_pricelist.id
return {'value':{'pricelist_id': pricelist}}
def _amount_total(self, cr, uid, ids, field_name, arg, context):
""" Calculates amount_tax of order line
@param field_names: Names of fields.
@return: Dictionary of values """
cr.execute("""
SELECT
p.id,
@ -110,6 +136,13 @@ class pos_order(osv.osv):
return res
def _get_date_payment2(self, cr, uid, ids, context, *a):
# Todo need to check this function
""" Find payment Date
@param field_names: Names of fields.
@return: Dictionary of values """
res = {}
pay_obj = self.pool.get('account.bank.statement')
stat_obj_line = self.pool.get('account.bank.statement.line')
@ -132,7 +165,12 @@ class pos_order(osv.osv):
if val:
res[order.id]=val
return res
def _get_date_payment(self, cr, uid, ids, context, *a):
""" Find Validation Date
@return: Dictionary of values """
res = {}
pay_obj = self.pool.get('pos.payment')
tot =0.0
@ -162,6 +200,10 @@ class pos_order(osv.osv):
return res
def _amount_tax(self, cr, uid, ids, field_name, arg, context):
""" Calculates Taxes of order
@return: Dictionary of values """
res = {}
tax_obj = self.pool.get('account.tax')
for order in self.browse(cr, uid, ids):
@ -184,6 +226,10 @@ class pos_order(osv.osv):
return res
def _total_payment(self, cr, uid, ids, field_name, arg, context):
""" Calculates Total payment of order
@return: Dictionary of values """
res = {}
i=0
for order in self.browse(cr, uid, ids):
@ -195,6 +241,10 @@ class pos_order(osv.osv):
return {order.id:val}
def _total_return(self, cr, uid, ids, field_name, arg, context):
""" Calculates Total Returned from the order
@return: Dictionary of values """
res = {}
for order in self.browse(cr, uid, ids):
val = 0.0
@ -203,11 +253,17 @@ class pos_order(osv.osv):
res[order.id] = val
return res
def payment_get(self, cr, uid, ids, context=None):
cr.execute("select id from pos_payment where order_id =ANY(%s)",(ids,))
return [i[0] for i in cr.fetchall()]
# def payment_get(self, cr, uid, ids, context=None):
# """ Calculates Total Returned from the order
# @return: Dictionary of values """
# cr.execute("select id from pos_payment where order_id =ANY(%s)",(ids,))
# return [i[0] for i in cr.fetchall()]
def _sale_journal_get(self, cr, uid, context):
""" To get sale journal for this order"
@return: journal """
journal_obj = self.pool.get('account.journal')
res = journal_obj.search(cr, uid,
[('type', '=', 'sale')], limit=1)
@ -217,6 +273,10 @@ class pos_order(osv.osv):
return False
def _shop_get(self, cr, uid, context):
""" To get Shop for this order"
@return: Shop id """
company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
res = self.pool.get('sale.shop').search(cr, uid, [])
# res = self.pool.get('sale.shop').search(cr, uid, [('company_id', '=', company.id)])
@ -225,12 +285,9 @@ class pos_order(osv.osv):
else:
return False
def _receivable_get(self, cr, uid, context=None):
prop_obj = self.pool.get('ir.property')
res = prop_obj.get(cr, uid, 'property_account_receivable', 'res.partner', context=context)
return res
def copy(self, cr, uid, id, default=None, context={}):
if not default:
default = {}
default.update({
@ -246,6 +303,10 @@ class pos_order(osv.osv):
return super(pos_order, self).copy(cr, uid, id, default, context)
def _get_v( self, cr, uid, ids,*a):
""" Changed the Validation state of order
@return: State """
flag=False
res_company = self.pool.get('res.company')
res_obj = self.pool.get('res.users')
@ -333,6 +394,11 @@ class pos_order(osv.osv):
def _select_pricelist(self, cr, uid, context):
""" To get default pricelist for the order"
@param name: Names of fields.
@return: pricelist ID
"""
pricelist = self.pool.get('product.pricelist').search(cr, uid, [('name', '=', 'Public Pricelist')])
if pricelist:
return pricelist[0]
@ -340,6 +406,11 @@ class pos_order(osv.osv):
return False
def _journal_default(self, cr, uid, context={}):
""" To get default pricelist for the order"
@param name: Names of fields.
@return: journal ID
"""
journal_list = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')])
if journal_list:
return journal_list[0]
@ -365,6 +436,11 @@ class pos_order(osv.osv):
def test_order_lines(self, cr, uid, order, context={}):
""" Test order line is created or not for the order "
@param name: Names of fields.
@return: True
"""
if not order.lines:
raise osv.except_osv(_('Error'), _('No order lines defined for this sale.'))
@ -376,6 +452,10 @@ class pos_order(osv.osv):
return True
def test_paid(self, cr, uid, ids, context=None):
""" Test all amount is paid for this order
@return: True
"""
for order in self.browse(cr, uid, ids, context):
if order.lines and not order.amount_total:
return True
@ -385,7 +465,9 @@ class pos_order(osv.osv):
return True
def _get_qty_differences(self, orders, old_picking):
"""check if the customer changed the product quantity"""
"""check if the customer changed the product quantity """
order_dict = {}
for order in orders:
for line in order.lines:
@ -407,7 +489,9 @@ class pos_order(osv.osv):
return diff_dict
def _split_picking(self, cr, uid, ids, context, old_picking, diff_dict):
"""if the customer changes the product quantity, split the picking in two"""
# create a copy of the original picking and adjust the product qty:
picking_model = self.pool.get('stock.picking')
defaults = {
@ -445,7 +529,9 @@ class pos_order(osv.osv):
line.unlink(context=context)
def create_picking(self, cr, uid, ids, context={}):
"""Create a picking for each order and validate it."""
picking_obj = self.pool.get('stock.picking')
orders = self.browse(cr, uid, ids, context)
@ -510,6 +596,10 @@ class pos_order(osv.osv):
return True
def set_to_draft(self, cr, uid, ids, *args):
""" Changes order state to draft
@return: True
"""
if not len(ids):
return False
@ -521,6 +611,10 @@ class pos_order(osv.osv):
return True
def button_invalidate(self, cr, uid, ids, *args):
""" Check the access for the sale order
@return: True
"""
res_obj = self.pool.get('res.company')
try:
part_company=res_obj.browse(cr,uid,uid) and res_obj.browse(cr,uid,uid).parent_id and res_obj.browse(cr,uid,uid).parent_id.id or None
@ -531,6 +625,10 @@ class pos_order(osv.osv):
return True
def button_validate(self, cr, uid, ids, *args):
""" Check the access for the sale order and update the date_payment
@return: True
"""
res_obj = self.pool.get('res.company')
try:
part_company=res_obj.browse(cr,uid,uid) and res_obj.browse(cr,uid,uid).parent_id and res_obj.browse(cr,uid,uid).parent_id.id or None
@ -549,12 +647,18 @@ class pos_order(osv.osv):
def cancel_order(self, cr, uid, ids, context=None):
""" Changes order state to cancel
@return: True
"""
self.write(cr, uid, ids, {'state': 'cancel'})
self.cancel_picking(cr, uid, ids, context={})
return True
def add_payment(self, cr, uid, order_id, data, context=None):
"""Create a new payment for the order"""
res_obj = self.pool.get('res.company')
statementl_obj = self.pool.get('account.bank.statement.line')
prod_obj = self.pool.get('product.product')
@ -597,7 +701,7 @@ class pos_order(osv.osv):
args['statement_id']= statement_id
args['pos_statement_id']= order_id
args['journal_id']= data['journal']
statement_line_id = self.pool.get('account.bank.statement.line').create(cr, uid, args)
statement_line_id = statementl_obj.create(cr, uid, args)
ids_new.append(statement_id)
wf_service = netsvc.LocalService("workflow")
@ -607,7 +711,9 @@ class pos_order(osv.osv):
return statement_id
def add_product(self, cr, uid, order_id, product_id, qty, context=None):
"""Create a new order line the order"""
line_obj = self.pool.get('pos.order.line')
values = self.read(cr, uid, order_id, ['partner_id', 'pricelist_id'])
@ -629,6 +735,9 @@ class pos_order(osv.osv):
return order_line_id
def refund(self, cr, uid, ids, context={}):
"""Create a copy of order for refund order"""
clone_list = []
line_obj = self.pool.get('pos.order.line')
@ -653,9 +762,13 @@ class pos_order(osv.osv):
return clone_list
def action_invoice(self, cr, uid, ids, context={}):
"""Create a invoice of order """
res_obj = self.pool.get('res.company')
inv_ref = self.pool.get('account.invoice')
inv_line_ref = self.pool.get('account.invoice.line')
product_obj= self.pool.get('product.product')
inv_ids = []
for order in self.browse(cr, uid, ids, context):
@ -693,7 +806,7 @@ class pos_order(osv.osv):
'product_id': line.product_id.id,
'quantity': line.qty,
}
inv_name = self.pool.get('product.product').name_get(cr, uid, [line.product_id.id], context=context)[0][1]
inv_name = product_obj.name_get(cr, uid, [line.product_id.id], context=context)[0][1]
inv_line.update(inv_line_ref.product_id_change(cr, uid, [],
line.product_id.id,
@ -714,6 +827,9 @@ class pos_order(osv.osv):
return inv_ids
def create_account_move(self, cr, uid, ids, context=None):
"""Create a account move line of order """
account_move_obj = self.pool.get('account.move')
account_move_line_obj = self.pool.get('account.move.line')
account_period_obj = self.pool.get('account.period')

View File

@ -26,6 +26,7 @@ import netsvc
class account_bank_statement(osv.osv):
_inherit = 'account.bank.statement'
_columns = {
'company_id':fields.many2one('res.company', 'Company', required=True),
@ -36,11 +37,24 @@ class account_bank_statement(osv.osv):
account_bank_statement()
class account_bank_statement_line(osv.osv):
def _default_company(self, cr, uid, context={}):
""" To get default company for the object"
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of bank statement ids
@param context: A standard dictionary for contextual values
@return: company
"""
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
if user.company_id:
return user.company_id.id
return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
_inherit = 'account.bank.statement.line'
_columns = {
'company_id':fields.many2one('res.company', 'Company', required=True),

View File

@ -33,7 +33,7 @@ class pos_invoice(report_sxw.rml_parse):
self.localcontext.update({
'time': time,
})
print
def set_context(self, objects, data, ids, report_type=None):
super(pos_invoice, self).set_context(objects, data, ids, report_type)

View File

@ -52,7 +52,7 @@ class pos_payment_report(report_sxw.rml_parse):
"where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id " \
"and po.state in ('paid','invoiced') and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date = current_date")
data=self.cr.dictfetchall()
print data
for d in data:
self.total += d['price_unit'] * d['qty']
return data

View File

@ -58,12 +58,12 @@
<field name="starting_details_ids" nolabel = "1" colspan="4">
<tree string = "Starting Details" editable="bottom">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal" sum="Total"/>
</tree>
<form string = "Ending Details">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal"/>
</form>
</field>
@ -72,12 +72,12 @@
<field name="ending_details_ids" nolabel = "1" colspan="4">
<tree string = "Ending Details" editable="bottom">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal" sum="Total"/>
</tree>
<form string = "Ending Details">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal"/>
</form>
</field>
@ -135,12 +135,12 @@
<field name="ending_details_ids" nolabel = "1" colspan="4">
<tree string = "Ending Details" editable="bottom">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal" sum="Total"/>
</tree>
<form string = "Ending Details">
<field name="pieces"/>
<field name="number" on_change="on_change_sub2(pieces,number, parent.balance_end)"/>
<field name="number" on_change="on_change_sub(pieces,number, parent.balance_end)"/>
<field name="subtotal"/>
</form>
</field>

View File

@ -137,17 +137,21 @@ class pos_make_payment(osv.osv_memory):
jrnl_used=jrnl_obj.browse(cr,uid,data['journal'])
order_obj.write(cr, uid, [record_id], {'invoice_wanted': invoice_wanted})
order_obj.add_payment(cr, uid, record_id, data, context=context)
if amount<=0.0:
context.update({'flag':True})
order_obj.action_paid(cr,uid,[record_id],context)
# Todo need to check
# if amount<=0.0:
# context.update({'flag':True})
# order_obj.action_paid(cr,uid,[record_id],context)
if order_obj.test_paid(cr, uid, [record_id]):
if order.partner_id and order.invoice_wanted:
return self.create_invoice(cr,uid,ids,context)
else:
order_obj.action_paid(cr,uid,[record_id],context)
order_obj.write(cr, uid, [record_id],{'state':'paid'})
return self.print_report(cr, uid, ids, context)
if order.amount_paid > 0.0:
context.update({'flag': True})
# Todo need to check
order_obj.action_paid(cr, uid, [record_id], context)
self.pool.get('pos.order').write(cr, uid, [record_id],{'state':'advance'})
return self.print_report(cr, uid, ids, context)
return {}

View File

@ -266,6 +266,7 @@ def _create_returns(self, cr, uid, data, context):
return res
def _create_returns2(self, cr, uid, data, context):
act={}
pool = pooler.get_pool(cr.dbname)
order_obj = pool.get('pos.order')
line_obj = pool.get('pos.order.line')
@ -283,46 +284,49 @@ def _create_returns2(self, cr, uid, data, context):
res=cr.fetchone()
location_id=res and res[0] or None
stock_dest_id = int(val.split(',')[1])
if order_id.last_out_picking.id:
new_picking=picking_obj.copy(cr, uid, order_id.last_out_picking.id, {'name':'%s (return)' % order_id.name,
'move_lines':[], 'state':'draft', 'type':'in',
'type':'in',
'date':date_cur, })
new_order=order_obj.copy(cr,uid,order_id.id, {'name': 'Refund %s'%order_id.name,
'lines':[],
'statement_ids':[],
'last_out_picking':[]})
for line in order_id.lines:
for r in data['form'].get('returns',[]):
if line.id==r and (data['form']['return%s' %r]!=0.0):
new_move=stock_move_obj.create(cr, uid,{
'product_qty': data['form']['return%s' %r],
'product_uos_qty': uom_obj._compute_qty(cr, uid,data['form']['return%s' %r] ,line.product_id.uom_id.id),
'picking_id':new_picking,
'product_uom':line.product_id.uom_id.id,
'location_id':location_id,
'product_id':line.product_id.id,
'location_dest_id':stock_dest_id,
'name':'%s (return)' %order_id.name,
'date':date_cur,
'date_planned':date_cur,})
line_obj.copy(cr,uid,line.id,{'qty':-data['form']['return%s' %r],
'order_id': new_order,
})
order_obj.write(cr,uid, new_order, {'state':'done'})
wf_service.trg_validate(uid, 'stock.picking',new_picking,'button_confirm', cr)
picking_obj.force_assign(cr, uid, [new_picking], context)
act = {
'domain': "[('id', 'in', ["+str(new_order)+"])]",
'name': 'Refunded Orders',
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'pos.order',
'auto_refresh':0,
'res_id':new_order,
'view_id': False,
'type': 'ir.actions.act_window'
}
else:
raise wizard.except_wizard(_('Error'), _('Last out picking No find!'))
new_picking=picking_obj.copy(cr, uid, order_id.last_out_picking.id, {'name':'%s (return)' % order_id.name,
'move_lines':[], 'state':'draft', 'type':'in',
'type':'in',
'date':date_cur, })
new_order=order_obj.copy(cr,uid,order_id.id, {'name': 'Refund %s'%order_id.name,
'lines':[],
'statement_ids':[],
'last_out_picking':[]})
for line in order_id.lines:
for r in data['form'].get('returns',[]):
if line.id==r and (data['form']['return%s' %r]!=0.0):
new_move=stock_move_obj.create(cr, uid,{
'product_qty': data['form']['return%s' %r],
'product_uos_qty': uom_obj._compute_qty(cr, uid,data['form']['return%s' %r] ,line.product_id.uom_id.id),
'picking_id':new_picking,
'product_uom':line.product_id.uom_id.id,
'location_id':location_id,
'product_id':line.product_id.id,
'location_dest_id':stock_dest_id,
'name':'%s (return)' %order_id.name,
'date':date_cur,
'date_planned':date_cur,})
line_obj.copy(cr,uid,line.id,{'qty':-data['form']['return%s' %r],
'order_id': new_order,
})
order_obj.write(cr,uid, new_order, {'state':'done'})
wf_service.trg_validate(uid, 'stock.picking',new_picking,'button_confirm', cr)
picking_obj.force_assign(cr, uid, [new_picking], context)
act = {
'domain': "[('id', 'in', ["+str(new_order)+"])]",
'name': 'Refunded Orders',
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'pos.order',
'auto_refresh':0,
'res_id':new_order,
'view_id': False,
'type': 'ir.actions.act_window'
}
return act
def test(self,cr,uid,data,context={}):
# import pdb; pdb.set_trace()

View File

@ -34,12 +34,15 @@
'depends': ['base', 'account', 'stock', 'process'],
'init_xml': [],
'update_xml': [
'security/purchase_security.xml',
'security/ir.model.access.csv',
'purchase_workflow.xml',
'purchase_sequence.xml',
'purchase_data.xml',
'wizard/purchase_order_group_view.xml',
'wizard/purchase_installer.xml',
'wizard/purchase_line_invoice_view.xml',
'purchase_view.xml',
'purchase_report.xml',
'stock_view.xml',

View File

@ -246,6 +246,7 @@ class purchase_order(osv.osv):
return {'value':{'location_id': res, 'dest_address_id': False}}
def onchange_partner_id(self, cr, uid, ids, part):
if not part:
return {'value':{'partner_address_id': False, 'fiscal_position': False}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['default'])
@ -259,12 +260,18 @@ class purchase_order(osv.osv):
return True
def wkf_confirm_order(self, cr, uid, ids, context={}):
todo = []
for po in self.browse(cr, uid, ids):
if self.pool.get('res.partner.event.type').check(cr, uid, 'purchase_open'):
self.pool.get('res.partner.event').create(cr, uid, {'name':'Purchase Order: '+po.name, 'partner_id':po.partner_id.id, 'date':time.strftime('%Y-%m-%d %H:%M:%S'), 'user_id':uid, 'partner_type':'retailer', 'probability': 1.0, 'planned_cost':po.amount_untaxed})
if not po.order_line:
raise osv.except_osv(_('Error !'),_('You can not confirm purchase order without Purchase Order Lines.'))
for line in po.order_line:
if line.state=='draft':
todo.append(line.id)
current_name = self.name_get(cr, uid, ids)[0][1]
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
for id in ids:
self.write(cr, uid, [id], {'state' : 'confirmed', 'validator' : uid})
return True
@ -312,11 +319,13 @@ class purchase_order(osv.osv):
def action_invoice_create(self, cr, uid, ids, *args):
res = False
journal_obj = self.pool.get('account.journal')
for o in self.browse(cr, uid, ids):
il = []
todo = []
for ol in o.order_line:
todo.append(ol.id)
if ol.product_id:
a = ol.product_id.product_tmpl_id.property_account_expense.id
if not a:
@ -352,7 +361,7 @@ class purchase_order(osv.osv):
}
inv_id = self.pool.get('account.invoice').create(cr, uid, inv, {'type':'in_invoice'})
self.pool.get('account.invoice').button_compute(cr, uid, [inv_id], {'type':'in_invoice'}, set_total=True)
self.pool.get('purchase.order.line').write(cr, uid, todo, {'invoiced':True})
self.write(cr, uid, [o.id], {'invoice_id': inv_id})
res = inv_id
return res
@ -579,10 +588,22 @@ class purchase_order_line(osv.osv):
'notes': fields.text('Notes', translate=True),
'order_id': fields.many2one('purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'),
'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company')
'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company'),
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', required=True, readonly=True,
help=' * The \'Draft\' state is set automatically when purchase order in draft state. \
\n* The \'Confirmed\' state is set automatically as confirm when purchase order in confirm state. \
\n* The \'Done\' state is set automatically when purchase order is set as done. \
\n* The \'Cancelled\' state is set automatically when user cancel purchase order.'),
'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
}
_defaults = {
'product_qty': lambda *a: 1.0
'product_qty': lambda *a: 1.0,
'state': lambda *args: 'draft',
'invoiced': lambda *a: 0,
}
_table = 'purchase_order_line'
_name = 'purchase.order.line'
@ -590,7 +611,7 @@ class purchase_order_line(osv.osv):
def copy_data(self, cr, uid, id, default=None,context={}):
if not default:
default = {}
default.update({'state':'draft', 'move_ids':[]})
default.update({'state':'draft', 'move_ids':[],'invoiced':0,'invoice_lines':[]})
return super(purchase_order_line, self).copy_data(cr, uid, id, default, context)
def product_id_change(self, cr, uid, ids, pricelist, product, qty, uom,
@ -658,14 +679,17 @@ class purchase_order_line(osv.osv):
return res
def product_uom_change(self, cr, uid, ids, pricelist, product, qty, uom,
partner_id, date_order=False):
partner_id, date_order=False,fiscal_position=False):
res = self.product_id_change(cr, uid, ids, pricelist, product, qty, uom,
partner_id, date_order=date_order)
partner_id, date_order=date_order,fiscal_position=fiscal_position)
if 'product_uom' in res['value']:
del res['value']['product_uom']
if not uom:
res['value']['price_unit'] = 0.0
return res
def action_confirm(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'confirmed'}, context)
return True
purchase_order_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -92,7 +92,9 @@
<field name="product_qty"/>
<field name="product_uom"/>
<field name="price_unit"/>
<field name="price_subtotal" groups="base.group_extended"/>
<field name="price_subtotal" groups="base.group_extended"/>
<field name="invoiced"/>
<field name="state"/>
</tree>
<!-- default form view -->
</field>
@ -224,7 +226,7 @@
<page string="Order Line">
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,notes)"/>
<field context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_qty" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id,parent.date_order,parent.fiscal_position,date_planned,name,price_unit,notes)"/>
<field name="product_uom" on_change="product_uom_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
<field name="product_uom" on_change="product_uom_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position)"/>
<field colspan="4" name="name"/>
<field name="date_planned" widget="date"/>
<field name="price_unit"/>
@ -242,8 +244,15 @@
<field name="account_analytic_id" colspan="4"/>
<separator colspan="4" string="Taxes"/>
<field colspan="4" nolabel="1" name="taxes_id" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
<separator colspan="4" string="Manual Invoices"/>
<field name="invoiced"/>
<newline/>
<field colspan="4" name="invoice_lines" nolabel="1" widget="many2many"/>
</page>
</notebook>
<group>
<field name="state" />
</group>
</form>
</field>
</record>
@ -262,6 +271,7 @@
<field name="product_uom"/>
<field name="price_unit"/>
<field name="price_subtotal"/>
<field name="invoiced"/>
</tree>
</field>
</record>
@ -280,5 +290,58 @@
name="Product purchases"
res_model="purchase.order.line"
src_model="product.product"/>
<!--
<record model="ir.values" id="action_merge_purchase_order">
<field name="object" eval="1" />
<field name="name">Purchase Order</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_view_purchase_order_group'))" />
<field name="key">action</field>
<field name="model">purchase.order</field>
</record>
-->
<record id="purchase_line_form_action" model="ir.actions.act_window">
<field name="name">Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<record id="purchase_line_form_action_form" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<menuitem action="purchase_line_form_action" id="menu_purchase_line_form_action" parent="base.menu_purchase_root"/>
<record id="purchase_line_form_action2" model="ir.actions.act_window">
<field name="name">Uninvoiced Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree2" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
<record id="purchase_line_form_action_form2" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
<menuitem action="purchase_line_form_action2" id="menu_purchase_line_order_draft" parent="menu_purchase_line_form_action"/>
</data>
</openerp>

View File

@ -20,6 +20,7 @@
##############################################################################
import purchase_order_group
import purchase_installer
import purchase_line_invoice
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2004-2009 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
@ -15,8 +15,17 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv
class purchase_installer(osv.osv_memory):
_name = 'purchase.installer'
_inherit = 'res.config.installer'
_columns = {
'purchase_requisition':fields.boolean('Purchase Requisition'),
}
purchase_installer()
import wizard_purchase_line_invoice

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_purchase_install_module_form" model="ir.ui.view">
<field name="name">Purchase Requisition</field>
<field name="model">purchase.installer</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.res_config_installer"/>
<field name="arch" type="xml">
<data>
<form position="attributes">
<attribute name="string">Purchase Modules Installation</attribute>
</form>
<xpath expr="//label[@string='description']"
position="attributes">
<attribute name="string"> This module allows you to manage your Purchase Requisition.</attribute>
</xpath>
<separator string="title" position="replace"/>
<group colspan="8">
<separator string="Purchase Requisition" colspan="4"/>
<field name="purchase_requisition"/>
</group>
</data>
</field>
</record>
<record id="action_purchase_install_module" model="ir.actions.act_window">
<field name="name">Purchase Profile : Install Extra Modules</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.installer</field>
<field name="view_id" ref="view_purchase_install_module_form"/>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="purchase_installer_todo" model="ir.actions.todo">
<field name="action_id" ref="action_purchase_install_module"/>
<field name="sequence">3</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,132 @@
# -*- 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 ir
from osv import osv
from tools.translate import _
class purchase_line_invoice(osv.osv_memory):
""" To create invoice for purchase order line"""
_name = 'purchase.order.line_invoice'
_description = 'Purchase Order Line Make Invoice'
def makeInvoices(self, cr, uid, ids, context):
"""
To get Purchase Order line and create Invoice
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return : retrun view of Invoice
"""
record_ids = context.get('active_ids',[])
if record_ids:
res = False
invoices = {}
invoice_obj=self.pool.get('account.invoice')
purchase_line_obj=self.pool.get('purchase.order.line')
property_obj=self.pool.get('ir.property')
account_fiscal_obj=self.pool.get('account.fiscal.position')
invoice_line_obj=self.pool.get('account.invoice.line')
def make_invoice(order, lines):
a = order.partner_id.property_account_payable.id
if order.partner_id and order.partner_id.property_payment_term.id:
pay_term = order.partner_id.property_payment_term.id
else:
pay_term = False
inv = {
'name': order.name,
'origin': order.name,
'type': 'in_invoice',
'reference': "P%dPO%d" % (order.partner_id.id, order.id),
'account_id': a,
'partner_id': order.partner_id.id,
'address_invoice_id': order.partner_address_id.id,
'address_contact_id': order.partner_address_id.id,
'invoice_line': [(6,0,lines)],
'currency_id' : order.pricelist_id.currency_id.id,
'comment': order.notes,
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id
}
inv_id = invoice_obj.create(cr, uid, inv)
return inv_id
for line in purchase_line_obj.browse(cr,uid,record_ids):
if (not line.invoiced) and (line.state not in ('draft','cancel')):
if not line.order_id.id in invoices:
invoices[line.order_id.id] = []
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_expense.id
if not a:
a = line.product_id.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error !'),
_('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
(line.product_id.name, line.product_id.id,))
else:
a = property_obj.get(cr, uid,
'property_account_expense_categ', 'product.category',
context=context)
fpos = line.order_id.fiscal_position or False
a = account_fiscal_obj.map_account(cr, uid, fpos, a)
inv_id = invoice_line_obj.create(cr, uid, {
'name': line.name,
'origin': line.order_id.name,
'account_id': a,
'price_unit': line.price_unit,
'quantity': line.product_qty,
'uos_id': line.product_uom.id,
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
'note': line.notes,
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
})
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
purchase_line_obj.write(cr, uid, [line.id], {'invoiced': True})
invoices[line.order_id.id].append((line,inv_id))
res = []
for result in invoices.values():
order = result[0][0].order_id
il = map(lambda x: x[1], result)
res.append(make_invoice(order, il))
return {
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",
'name': _('Supplier Invoices'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'view_id': False,
'context': "{'type':'in_invoice'}",
'type': 'ir.actions.act_window'
}
purchase_line_invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Make the invoice-->
<record id="view_purchase_line_invoice" model="ir.ui.view">
<field name="name">Control invoices</field>
<field name="model">purchase.order.line_invoice</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Select an Open Sale Order">
<separator colspan="4" string="Do you want to generate the supplier invoices ?" />
<group col="2" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="makeInvoices" string="Confirm"
colspan="1" type="object" icon="gtk-ok" />
</group>
</form>
</field>
</record>
<act_window name="Control invoices"
res_model="purchase.order.line_invoice"
src_model="purchase.order.line"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_view_purchase_line_invoice"/>
</data>
</openerp>

View File

@ -1,41 +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/>.
#
##############################################################################
{
'name': 'Purchase Management - Manual Control of Invoice',
'version': '1.1',
'category': 'Generic Modules/Sales & Purchases',
'description': """Module for purchase management, manual control of invoice""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['purchase'],
'init_xml': [],
'update_xml': [
'purchase_manual_view.xml',
'purchase_manual_wizard.xml',
],
'demo_xml': [],
'installable': True,
'active': False,
# 'certificate': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,81 +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/>.
#
##############################################################################
from osv import fields
from osv import osv
import netsvc
class purchase_order_line(osv.osv):
_inherit='purchase.order.line'
_columns = {
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', required=True, readonly=True,
help=' * The \'Draft\' state is set automatically when purchase order in draft state. \
\n* The \'Confirmed\' state is set automatically as confirm when purchase order in confirm state. \
\n* The \'Done\' state is set automatically when purchase order is set as done. \
\n* The \'Cancelled\' state is set automatically when user cancel purchase order.'),
'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
}
_defaults = {
'state': lambda *args: 'draft',
'invoiced': lambda *a: 0,
}
def copy_data(self, cr, uid, id, default=None, context={}):
print 'copy called'
if not default:
default = {}
default.update({
'state':'draft',
'invoiced':0,
'invoice_lines':[],
})
return super(purchase_order_line, self).copy_data(cr, uid, id, default, context)
def action_confirm(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'confirmed'}, context)
return True
purchase_order_line()
class purchase_order(osv.osv):
_inherit='purchase.order'
def action_invoice_create(self, cr, uid, ids, context={}):
print 'Invoice Create'
res = super(purchase_order, self).action_invoice_create(cr, uid, ids, context)
for po in self.browse(cr, uid, ids, context):
todo = []
for line in po.order_line:
todo.append(line.id)
self.pool.get('purchase.order.line').write(cr, uid, todo, {'invoiced':True}, context)
return res
def wkf_confirm_order(self, cr, uid, ids, context={}):
res = super(purchase_order, self).wkf_confirm_order(cr, uid, ids, context)
todo = []
for po in self.browse(cr, uid, ids, context):
for line in po.order_line:
if line.state=='draft':
todo.append(line.id)
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
return res
purchase_order()

View File

@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
#
# Define PO Line Views
#
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='Purchase Order']/field[@name='order_line']/tree/field[@name='price_subtotal']" position="after">
<field name="invoiced"/>
<field name="state"/>
</xpath>
</field>
</record>
<record id="purchase_order_line_form" model="ir.ui.view">
<field name="name">purchase.order.line.form</field>
<field name="model">purchase.order.line</field>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_line_form"/>
<field name="priority">17</field>
<field name="arch" type="xml">
<data>
<xpath expr="/form/notebook/page[@string='Invoicing']" position="inside">
<separator colspan="4" string="Manual Invoices"/>
<field name="invoiced"/>
<newline/>
<field colspan="4" name="invoice_lines" nolabel="1" widget="many2many"/>
</xpath>
<xpath expr="/form/notebook" position="after">
<group>
<field name="state" />
</group>
</xpath>
</data>
</field>
</record>
<record id="purchase_order_line_tree" model="ir.ui.view">
<field name="name">purchase.order.line.tree</field>
<field name="model">purchase.order.line</field>
<field name="type">tree</field>
<field name="inherit_id" ref="purchase.purchase_order_line_tree"/>
<field name="arch" type="xml">
<field name="price_subtotal" position="after">
<field name="invoiced"/>
</field>
</field>
</record>
#
# Inherit PO view to get buttons
#
<record id="purchase_line_form_action" model="ir.actions.act_window">
<field name="name">Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<record id="purchase_line_form_action_form" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<record id="purchase_line_form_action2" model="ir.actions.act_window">
<field name="name">Uninvoiced Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree2" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
<record id="purchase_line_form_action_form2" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
</data>
</openerp>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<wizard
id="wizard_purchase_order_line_invoice"
keyword="client_action_multi"
model="purchase.order.line"
name="purchase.order.line.make_invoice"
multi="True"
string="Invoice Received"/>
</data>
</openerp>

View File

@ -1,162 +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 ir
import pooler
from osv import osv
from tools.translate import _
invoice_form = """<?xml version="1.0"?>
<form string="Control invoices">
<separator colspan="4" string="Do you want to generate the supplier invoices ?" />
</form>
"""
invoice_fields = {
}
def _makeInvoices(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
res = False
invoices = {}
def make_invoice(order, lines):
a = order.partner_id.property_account_payable.id
if order.partner_id and order.partner_id.property_payment_term.id:
pay_term = order.partner_id.property_payment_term.id
else:
pay_term = False
inv = {
'name': order.name,
'origin': order.name,
'type': 'in_invoice',
'reference': "P%dPO%d" % (order.partner_id.id, order.id),
'account_id': a,
'partner_id': order.partner_id.id,
'address_invoice_id': order.partner_address_id.id,
'address_contact_id': order.partner_address_id.id,
'invoice_line': [(6,0,lines)],
'currency_id' : order.pricelist_id.currency_id.id,
'comment': order.notes,
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id
}
inv_id = pool.get('account.invoice').create(cr, uid, inv)
return inv_id
for line in pool.get('purchase.order.line').browse(cr,uid,data['ids']):
if (not line.invoiced) and (line.state not in ('draft','cancel')):
if not line.order_id.id in invoices:
invoices[line.order_id.id] = []
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_expense.id
if not a:
a = line.product_id.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error !'),
_('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
(line.product_id.name, line.product_id.id,))
else:
a = pool.get('ir.property').get(cr, uid,
'property_account_expense_categ', 'product.category',
context=context)
fpos = line.order_id.fiscal_position or False
a = pool.get('account.fiscal.position').map_account(cr, uid, fpos, a)
inv_id = pool.get('account.invoice.line').create(cr, uid, {
'name': line.name,
'origin': line.order_id.name,
'account_id': a,
'price_unit': line.price_unit,
'quantity': line.product_qty,
'uos_id': line.product_uom.id,
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
'note': line.notes,
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
})
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
pool.get('purchase.order.line').write(cr, uid, [line.id], {'invoiced': True})
invoices[line.order_id.id].append((line,inv_id))
res = []
for result in invoices.values():
order = result[0][0].order_id
il = map(lambda x: x[1], result)
res.append(make_invoice(order, il))
return {'invoice_ids': res}
return {
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",
'name': _('Supplier Invoices'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'view_id': False,
'context': "{'type':'in_invoice'}",
'type': 'ir.actions.act_window'
}
class line_make_invoice(wizard.interface):
def _open_invoice(self, cr, uid, data, context):
pool_obj = pooler.get_pool(cr.dbname)
model_data_ids = pool_obj.get('ir.model.data').search(cr,uid,[('model','=','ir.ui.view'),('name','=','invoice_supplier_form')])
resource_id = pool_obj.get('ir.model.data').read(cr,uid,model_data_ids,fields=['res_id'])[0]['res_id']
return {
'domain': "[('id','in', ["+','.join(map(str,data['form']['invoice_ids']))+"])]",
'name': 'Invoices',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'views': [(False,'tree'),(resource_id,'form')],
'context': "{'type':'in_invoice'}",
'type': 'ir.actions.act_window'
}
states = {
'init' : {
'actions': [],
'result': {
'type': 'form',
'arch': invoice_form,
'fields': invoice_fields,
'state': [
('end', 'Cancel'),
('invoice', 'Create invoices')
]
}
},
'invoice' : {
'actions' : [_makeInvoices],
'result' : {'type': 'state', 'state': 'open'}
},
'open': {
'actions': [],
'result': {'type':'action', 'action':_open_invoice, 'state':'end'}
}
}
line_make_invoice("purchase.order.line.make_invoice")
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,4 +19,6 @@
##############################################################################
import purchase_requisition
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -31,7 +31,10 @@
"depends" : ["purchase","mrp"],
"init_xml" : [],
"demo_xml" : [],
"update_xml" : ["purchase_requisition_view.xml","security/ir.model.access.csv","purchase_requisition_sequence.xml"],
"update_xml" : ["wizard/purchase_requisition_partner_view.xml",
"purchase_requisition_view.xml",
"security/ir.model.access.csv","purchase_requisition_sequence.xml"],
"active": False,
"installable": True
}

View File

@ -36,16 +36,47 @@ class purchase_requisition(osv.osv):
'user_id': fields.many2one('res.users', 'Responsible'),
'exclusive': fields.selection([('exclusive','Purchase Tender (exclusive)'),('multiple','Multiple Requisitions')],'Requisition Type', help="If the requisition is exclusive, it will cancel all purchase orders when you confirm one of them", required=True),
'description': fields.text('Description'),
'company_id': fields.many2one('res.company', 'Company', required=True),
'purchase_ids' : fields.one2many('purchase.order','requisition_id','Purchase Orders'),
'line_ids' : fields.one2many('purchase.requisition.line','requisition_id','Products to Purchase'),
'state': fields.selection([('draft','Draft'),('open','Open'),('cancel','Cancelled'),('close','Close')], 'State', required=True)
'state': fields.selection([('draft','Draft'),('open','Open'),('cancel','Cancelled'),('close','Close'),('done','Done')], 'State', required=True)
}
_defaults = {
'date_start': lambda *args: time.strftime('%Y-%m-%d %H:%M:%S'),
'state': lambda *args: 'open',
'exclusive': lambda *args: 'multiple',
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
'user_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).id ,
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'purchase.order.requisition'),
}
def tender_close(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'done', 'date_end': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def tender_open(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state':'open'}, context=context)
return True
def tender_cancel(self, cr, uid, ids, context={}):
purchase_order_obj = self.pool.get('purchase.order')
for purchase in self.browse(cr, uid, ids):
for purchase_id in purchase.purchase_ids:
if str(purchase_id.state) in('draft','wait'):
purchase_order_obj.action_cancel(cr,uid,[purchase_id.id])
self.write(cr, uid, ids, {'state': 'cancel'})
return True
def tender_confirm(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state':'done','date_end':time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
return True
def tender_reset(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'draft'})
return True
def tender_done(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state':'done'}, context=context)
return True
purchase_requisition()
class purchase_requisition_line(osv.osv):
@ -55,11 +86,34 @@ class purchase_requisition_line(osv.osv):
_columns = {
'product_id': fields.many2one('product.product', 'Product'),
'product_uom_id': fields.many2one('product.uom', 'Product UoM'),
'product_qty': fields.float('Date End', digits=(16,2)),
'product_qty': fields.float('Quantity', digits=(16,2)),
'requisition_id' : fields.many2one('purchase.requisition','Purchase Requisition', ondelete='cascade'),
'company_id': fields.many2one('res.company', 'Company', required=True),
'requisition_id' : fields.many2one('purchase.requisition','Purchase Requisition', ondelete='cascade')
}
def onchange_product_id(self, cr, uid, ids, product_id, context={}):
""" Changes UoM and name if product_id changes.
@param name: Name of the field
@param product_id: Changed product_id
@return: Dictionary of changed values
"""
value = {}
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, [product_id])[0]
value = {'product_uom_id': prod.uom_id.id}
return {'value': value}
_defaults = {
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
}
purchase_requisition_line()
class purchase_order(osv.osv):
_inherit = "purchase.order"
_description = "purchase order"
@ -74,8 +128,11 @@ class purchase_order(osv.osv):
if order.id<>po.id:
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'purchase.order', order.id, 'purchase_cancel', cr)
self.pool.get('purchase.requisition').write(cr, uid, [po.requisition_id.id], {'state':'close'})
self.pool.get('purchase.requisition').write(cr, uid, [po.requisition_id.id], {'state':'close','date_end':time.strftime('%Y-%m-%d %H:%M:%S')})
return res
purchase_order()
@ -93,6 +150,7 @@ product_product()
class mrp_procurement(osv.osv):
_inherit = 'mrp.procurement'
def make_po(self, cr, uid, ids, context={}):
sequence_obj=self.pool.get('ir.sequence')
res = super(mrp_procurement, self).make_po(cr, uid, ids, context)
for proc_id,po_id in res.items():
procurement = self.browse(cr, uid, proc_id)

View File

@ -39,30 +39,48 @@
<field name="date_start"/>
<field name="date_end"/>
<field name="origin"/>
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
<notebook colspan="4">
<page string="Products">
<field name="line_ids" colspan="4" nolabel="1">
<tree string="Products" editable="bottom">
<field name="product_id"/>
<field name="product_uom_id"/>
<field name="product_id" on_change="onchange_product_id(product_id)"/>
<field name="product_qty"/>
<field name="product_uom_id"/>
</tree>
<form string="Products" editable="bottom">
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom_id"/>
<field name="product_qty"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</form>
</field>
</page>
<page string="Notes">
<field name="description" colspan="4" nolabel="1"/>
</page>
<page string="Quotations">
<field name="purchase_ids" nolabel="1" colspan="4"/>
</page>
<group col="8" colspan="4">
<button name="%(action_purchase_requisition_partner)d" string="New RfQr" type="action" />
<label colspan="6" string=""/>
</group>
<field name="purchase_ids" nolabel="1" colspan="4"/>
</page>
</notebook>
<field name="state" select="1"/>
<separator colspan="4"/>
<group col="8" colspan="4">
<field name="state" select="1" readonly ="1"/>
<button name="tender_close" states="open,draft" string="Close" type="object" icon="gtk-close" />
<button name="tender_open" states="draft,in_progress" string="Open" type="object" icon="gtk-go-forward" />
<button name="tender_cancel" states="draft,open," string="Cancel" type="object" icon="gtk-cancel" />
<button name="tender_confirm" states="open" string="Confirm" type="object" icon="gtk-go-up" />
<button name="tender_reset" states="done,cancel" string="Reset to Draft" type="object" icon="gtk-convert" />
</group>
</form>
</field>
</record>
@ -81,11 +99,43 @@
</tree>
</field>
</record>
<record id="view_purchase_requisition_filter" model="ir.ui.view">
<field name="name">purchase.requisition.list.select</field>
<field name="model">purchase.requisition</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Purchase Requisition">
<group col='10' colspan='4'>
<filter icon="terp-purchase" string="Quotations" domain="[('state','=','draft')]" separator="1"/>
<filter icon="terp-purchase" string="Approved" domain="[('state','=','open')]" separator="1"/>
<separator orientation="vertical"/>
<field name="name" select="1" string="Requisition Reference"/>
<field name="purchase_ids" select="1"/>
<field name="user_id" select="1" widget="selection">
<filter icon="terp-partner" domain="[('create_uid','=',uid)]" help="My Requisition "/>
</field>
<field name="exclusive" select="1" />
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="10">
<filter string="State" icon="terp-sale" domain="[]" context="{'group_by':'state'}"/>
<filter string="Date Start" icon="terp-purchase" domain="[]" context="{'group_by':'date_start'}"/>
<filter string="Date End" icon="terp-purchase" domain="[]" context="{'group_by':'date_end'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_purchase_requisition">
<field name="name">Purchase Requisitions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.requisition</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_purchase_requisition_filter"/>
</record>
<menuitem

View File

@ -1,3 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_purchase_requisition","purchase.requisition","model_purchase_requisition",purchase.group_purchase_user,1,1,1,1
"access_purchase_requisition_line","purchase.requisition.line","model_purchase_requisition_line",purchase.group_purchase_user,1,1,1,1
"access_purchase_requisition","purchase.requisition","model_purchase_requisition","purchase.group_purchase_user",1,1,1,1
"access_purchase_requisition_line","purchase.requisition.line","model_purchase_requisition_line","purchase.group_purchase_user",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_purchase_requisition purchase.requisition model_purchase_requisition purchase.group_purchase_user 1 1 1 1
3 access_purchase_requisition_line purchase.requisition.line model_purchase_requisition_line purchase.group_purchase_user 1 1 1 1

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="group_purchase_requisition_manager" model="res.groups">
<field name="name">Purchase Requisition / Manager</field>
</record>
<record id="group_purchase_requisition_user" model="res.groups">
<field name="name">Purchase Requisition / User</field>
</record>
<record model="ir.rule.group" id="purchase_requisition_comp_rule_group">
<field name="name">Purchase Requisition multi-company</field>
<field name="model_id" ref="model_purchase_requisition"/>
<field name="global" eval="True"/>
</record>
<record model="ir.rule" id="purchase_requisition_comp_rule">
<field name="field_id" search="[('model','=','purchase.requisition'),('name','=','company_id')]" model="ir.model.fields"/>
<field name="rule_group" ref="purchase_requisition_comp_rule_group"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
<record model="ir.rule.group" id="purchase_requisition_line_comp_rule_group">
<field name="name">Purchase requisition Line multi-company</field>
<field name="model_id" ref="model_purchase_requisition_line"/>
<field name="global" eval="True"/>
</record>
<record model="ir.rule" id="purchase_requisition_line_comp_rule">
<field name="field_id" search="[('model','=','purchase.requisition.line'),('name','=','company_id')]" model="ir.model.fields"/>
<field name="rule_group" ref="purchase_requisition_line_comp_rule_group"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
</data>
</openerp>

View File

@ -19,6 +19,7 @@
#
##############################################################################
import purchase_manual
import wizard
import purchase_requisition_partner
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,132 @@
# -*- 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/>.
#
##############################################################################
from osv import fields, osv
from service import web_services
import netsvc
import pooler
import time
from mx import DateTime
from osv.orm import browse_record, browse_null
class purchase_requisition_partner(osv.osv_memory):
_name = "purchase.requisition.partner"
_description = "Purchase Requisition Partner"
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', required=True),
'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True),
}
def view_init(self, cr, uid, fields_list, context=None):
res = super(purchase_requisition_partner, self).view_init(cr, uid, fields_list, context=context)
record_id = context and context.get('active_id', False) or False
tender = self.pool.get('purchase.requisition').browse(cr, uid, record_id)
if not tender.line_ids:
raise osv.except_osv('Error!','No Product in Tender')
True
def onchange_partner_id(self, cr, uid, ids, partner_id):
addr = self.pool.get('res.partner').address_get(cr, uid, [partner_id], ['default'])
part = self.pool.get('res.partner').browse(cr, uid, partner_id)
return {'value':{'partner_address_id': addr['default']}}
def create_order(self, cr, uid, ids, context):
"""
To Create a purchase orders .
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs
@param context: A standard dictionary
@return: {}
"""
record_ids = context and context.get('active_ids', False)
if record_ids:
data = self.read(cr, uid, ids)
company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
order_obj = self.pool.get('purchase.order')
order_line_obj = self.pool.get('purchase.order.line')
partner_obj = self.pool.get('res.partner')
tender_line_obj = self.pool.get('purchase.requisition.line')
pricelist_obj = self.pool.get('product.pricelist')
prod_obj = self.pool.get('product.product')
tender_obj = self.pool.get('purchase.requisition')
acc_pos_obj = self.pool.get('account.fiscal.position')
partner_id = data[0]['partner_id']
supplier_data = partner_obj.browse(cr, uid,[ partner_id])[0]
address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery']
list_line=[]
purchase_order_line={}
for tender in tender_obj.browse(cr, uid, record_ids):
for line in tender.line_ids:
uom_id = line.product_id.uom_po_id and line.product_id.uom_po_id.id or False
newdate = DateTime.strptime(tender.date_start, '%Y-%m-%d %H:%M:%S')
newdate = newdate - DateTime.RelativeDateTime(days=company.po_lead)
newdate = newdate -(line.product_id.seller_ids and line.product_id.seller_ids[0].delay or DateTime.strptime(tender.date_start, '%Y-%m-%d %H:%M:%S') )
partner = line.product_id.seller_ids and line.product_id.seller_ids[0].name or supplier_data
pricelist_id = partner.property_product_pricelist_purchase and partner.property_product_pricelist_purchase.id
price = pricelist_obj.price_get(cr, uid, [pricelist_id], line.product_id.id, line.product_qty, False, {'uom': uom_id})[pricelist_id]
product = prod_obj.browse(cr, uid, line.product_id.id, context=context)
purchase_order_line= {
'name': product.partner_ref,
'product_qty': line.product_qty,
'product_id': line.product_id.id,
'product_uom': uom_id,
'price_unit': price,
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
'notes': product.description_purchase,
}
taxes_ids = line.product_id.product_tmpl_id.supplier_taxes_id
taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
purchase_order_line.update({
'taxes_id': [(6,0,taxes)]
})
list_line.append(purchase_order_line)
purchase_id = order_obj.create(cr, uid, {
'origin': tender.name,
'partner_id': partner_id,
'partner_address_id': address_id,
'pricelist_id': pricelist_id,
'location_id': line.product_id.product_tmpl_id.property_stock_production.id,
'company_id': tender.company_id.id,
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
'requisition_id':tender.id,
})
order_ids=[]
for order_line in list_line:
order_line.update({
'order_id': purchase_id
})
order_line_obj.create(cr,uid,order_line)
return {}
purchase_requisition_partner()

View File

@ -0,0 +1,32 @@
<openerp>
<data>
<record id="view_purchase_requisition_partner" model="ir.ui.view">
<field name="name">Purchase Requisition</field>
<field name="model">purchase.requisition.partner</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Purchase Requisition">
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
<field domain="[('partner_id','=',partner_id)]" name="partner_address_id"/>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="create_order" string="Create Orders" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_purchase_requisition_partner" model="ir.actions.act_window">
<field name="name">Purchase Requisition</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.requisition.partner</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="context">{'record_id' : active_id}</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -43,7 +43,9 @@ class sale_shop(osv.osv):
sale_shop()
def _incoterm_get(self, cr, uid, context={}):
def _incoterm_get(self, cr, uid, context=None):
if context is None:
context = {}
cr.execute('select code, code||\', \'||name from stock_incoterms where active')
return cr.fetchall()
@ -52,7 +54,9 @@ class sale_order(osv.osv):
_name = "sale.order"
_description = "Sale Order"
def copy(self, cr, uid, id, default=None, context={}):
def copy(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if not default:
default = {}
default.update({
@ -62,18 +66,22 @@ class sale_order(osv.osv):
'picking_ids': [],
'name': self.pool.get('ir.sequence').get(cr, uid, 'sale.order'),
})
return super(sale_order, self).copy(cr, uid, id, default, context)
return super(sale_order, self).copy(cr, uid, id, default, context=context)
def _amount_line_tax(self, cr, uid, line, context={}):
def _amount_line_tax(self, cr, uid, line, context=None):
if context is None:
context = {}
val = 0.0
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_uom_qty, line.order_id.partner_invoice_id.id, line.product_id, line.order_id.partner_id):
val += c['amount']
return val
def _amount_all(self, cr, uid, ids, field_name, arg, context):
def _amount_all(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
res = {}
cur_obj = self.pool.get('res.currency')
for order in self.browse(cr, uid, ids):
for order in self.browse(cr, uid, ids, context):
res[order.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
@ -83,13 +91,15 @@ class sale_order(osv.osv):
cur = order.pricelist_id.currency_id
for line in order.order_line:
val1 += line.price_subtotal
val += self._amount_line_tax(cr, uid, line, context)
val += self._amount_line_tax(cr, uid, line, context=context)
res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val)
res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1)
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res
def _picked_rate(self, cr, uid, ids, name, arg, context=None):
if context is None:
context = {}
if not ids:
return {}
res = {}
@ -116,12 +126,14 @@ class sale_order(osv.osv):
res[r] = 0.0
else:
res[r] = 100.0 * res[r][0] / res[r][1]
for order in self.browse(cr, uid, ids, context):
for order in self.browse(cr, uid, ids, context=context):
if order.shipped:
res[order.id] = 100.0
return res
def _invoiced_rate(self, cursor, user, ids, name, arg, context=None):
if context is None:
context = {}
res = {}
for sale in self.browse(cursor, user, ids, context=context):
if sale.invoiced:
@ -139,6 +151,8 @@ class sale_order(osv.osv):
return res
def _invoiced(self, cursor, user, ids, name, arg, context=None):
if context is None:
context = {}
res = {}
for sale in self.browse(cursor, user, ids, context=context):
res[sale.id] = True
@ -150,7 +164,9 @@ class sale_order(osv.osv):
res[sale.id] = False
return res
def _invoiced_search(self, cursor, user, obj, name, args, context):
def _invoiced_search(self, cursor, user, obj, name, args, context=None):
if context is None:
context = {}
if not len(args):
return []
clause = ''
@ -177,7 +193,9 @@ class sale_order(osv.osv):
return [('id', '=', 0)]
return [('id', 'in', [x[0] for x in res])]
def _get_order(self, cr, uid, ids, context={}):
def _get_order(self, cr, uid, ids, context=None):
if context is None:
context = {}
result = {}
for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context):
result[line.order_id.id] = True
@ -277,7 +295,9 @@ class sale_order(osv.osv):
# Form filling
def unlink(self, cr, uid, ids, context=None):
sale_orders = self.read(cr, uid, ids, ['state'])
if context is None:
context = {}
sale_orders = self.read(cr, uid, ids, ['state'], context=context)
unlink_ids = []
for s in sale_orders:
if s['state'] in ['draft', 'cancel']:
@ -336,7 +356,9 @@ class sale_order(osv.osv):
return {'value': val}
def shipping_policy_change(self, cr, uid, ids, policy, context={}):
def shipping_policy_change(self, cr, uid, ids, policy, context=None):
if context is None:
context = {}
if not policy:
return {}
inv_qty = 'order'
@ -347,6 +369,8 @@ class sale_order(osv.osv):
return {'value': {'invoice_quantity': inv_qty}}
def write(self, cr, uid, ids, vals, context=None):
if context is None:
context = {}
if 'order_policy' in vals:
if vals['order_policy'] == 'prepaid':
vals.update({'invoice_quantity': 'order'})
@ -354,7 +378,9 @@ class sale_order(osv.osv):
vals.update({'invoice_quantity': 'procurement'})
return super(sale_order, self).write(cr, uid, ids, vals, context=context)
def create(self, cr, uid, vals, context={}):
def create(self, cr, uid, vals, context=None):
if context is None:
context = {}
if 'order_policy' in vals:
if vals['order_policy'] == 'prepaid':
vals.update({'invoice_quantity': 'order'})
@ -362,17 +388,23 @@ class sale_order(osv.osv):
vals.update({'invoice_quantity': 'procurement'})
return super(sale_order, self).create(cr, uid, vals, context=context)
def button_dummy(self, cr, uid, ids, context={}):
def button_dummy(self, cr, uid, ids, context=None):
if context is None:
context = {}
return True
#FIXME: the method should return the list of invoices created (invoice_ids)
# and not the id of the last invoice created (res). The problem is that we
# cannot change it directly since the method is called by the sale order
# workflow and I suppose it expects a single id...
def _inv_get(self, cr, uid, order, context={}):
def _inv_get(self, cr, uid, order, context=None):
if context is None:
context = {}
return {}
def _make_invoice(self, cr, uid, order, lines, context={}):
def _make_invoice(self, cr, uid, order, lines, context=None):
if context is None:
context = {}
a = order.partner_id.property_account_receivable.id
if order.payment_term:
pay_term = order.payment_term.id
@ -408,7 +440,7 @@ class sale_order(osv.osv):
}
inv_obj = self.pool.get('account.invoice')
inv.update(self._inv_get(cr, uid, order))
inv_id = inv_obj.create(cr, uid, inv, context)
inv_id = inv_obj.create(cr, uid, inv, context=context)
data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], pay_term, time.strftime('%Y-%m-%d'))
if data.get('value', False):
inv_obj.write(cr, uid, [inv_id], data['value'], context=context)
@ -458,8 +490,10 @@ class sale_order(osv.osv):
cr.execute('insert into sale_order_invoice_rel (order_id,invoice_id) values (%s,%s)', (order.id, res))
return res
def action_invoice_cancel(self, cr, uid, ids, context={}):
for sale in self.browse(cr, uid, ids):
def action_invoice_cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
for sale in self.browse(cr, uid, ids, context=context):
for line in sale.order_line:
invoiced = False
for iline in line.invoice_lines:
@ -471,8 +505,10 @@ class sale_order(osv.osv):
self.write(cr, uid, ids, {'state': 'invoice_except', 'invoice_ids': False})
return True
def action_invoice_end(self, cr, uid, ids, context={}):
for order in self.browse(cr, uid, ids):
def action_invoice_end(self, cr, uid, ids, context=None):
if context is None:
context = {}
for order in self.browse(cr, uid, ids, context=context):
val = {'invoiced': True}
if order.state == 'invoice_except':
val['state'] = 'progress'
@ -487,10 +523,12 @@ class sale_order(osv.osv):
return True
def action_cancel(self, cr, uid, ids, context={}):
def action_cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
ok = True
sale_order_line_obj = self.pool.get('sale.order.line')
for sale in self.browse(cr, uid, ids):
for sale in self.browse(cr, uid, ids, context=context):
for pick in sale.picking_ids:
if pick.state not in ('draft', 'cancel'):
raise osv.except_osv(
@ -687,8 +725,10 @@ class sale_order(osv.osv):
return True
def action_ship_end(self, cr, uid, ids, context={}):
for order in self.browse(cr, uid, ids):
def action_ship_end(self, cr, uid, ids, context=None):
if context is None:
context = {}
for order in self.browse(cr, uid, ids, context=context):
val = {'shipped': True}
if order.state == 'shipping_except':
val['state'] = 'progress'
@ -742,24 +782,30 @@ sale_order()
# - update it on change product and unit price
# - use it in report if there is a uos
class sale_order_line(osv.osv):
def _amount_line_net(self, cr, uid, ids, field_name, arg, context):
def _amount_line_net(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
res = {}
for line in self.browse(cr, uid, ids):
for line in self.browse(cr, uid, ids, context=context):
res[line.id] = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
return res
def _amount_line(self, cr, uid, ids, field_name, arg, context):
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
res = {}
cur_obj = self.pool.get('res.currency')
for line in self.browse(cr, uid, ids):
for line in self.browse(cr, uid, ids, context=context):
res[line.id] = line.price_unit * line.product_uom_qty * (1 - (line.discount or 0.0) / 100.0)
cur = line.order_id.pricelist_id.currency_id
res[line.id] = cur_obj.round(cr, uid, cur, res[line.id])
return res
def _number_packages(self, cr, uid, ids, field_name, arg, context):
def _number_packages(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
res = {}
for line in self.browse(cr, uid, ids):
for line in self.browse(cr, uid, ids, context=context):
try:
res[line.id] = int(line.product_uom_qty / line.product_packaging.qty)
except:
@ -817,7 +863,9 @@ class sale_order_line(osv.osv):
'product_packaging': lambda *a: False
}
def invoice_line_create(self, cr, uid, ids, context={}):
def invoice_line_create(self, cr, uid, ids, context=None):
if context is None:
context = {}
def _get_line_qty(line):
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
if line.product_uos:
@ -825,7 +873,7 @@ class sale_order_line(osv.osv):
return line.product_uom_qty
else:
return self.pool.get('mrp.procurement').quantity_get(cr, uid,
line.procurement_id.id, context)
line.procurement_id.id, context=context)
def _get_line_uom(line):
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
@ -834,11 +882,11 @@ class sale_order_line(osv.osv):
return line.product_uom.id
else:
return self.pool.get('mrp.procurement').uom_get(cr, uid,
line.procurement_id.id, context)
line.procurement_id.id, context=context)
create_ids = []
sales = {}
for line in self.browse(cr, uid, ids, context):
for line in self.browse(cr, uid, ids, context=context):
if not line.invoiced:
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_income.id
@ -889,19 +937,25 @@ class sale_order_line(osv.osv):
wf_service.trg_write(uid, 'sale.order', sid, cr)
return create_ids
def button_cancel(self, cr, uid, ids, context={}):
def button_cancel(self, cr, uid, ids, context=None):
if context is None:
context = {}
for line in self.browse(cr, uid, ids, context=context):
if line.invoiced:
raise osv.except_osv(_('Invalid action !'), _('You cannot cancel a sale order line that has already been invoiced !'))
return self.write(cr, uid, ids, {'state': 'cancel'})
def button_confirm(self, cr, uid, ids, context={}):
def button_confirm(self, cr, uid, ids, context=None):
if context is None:
context = {}
return self.write(cr, uid, ids, {'state': 'confirmed'})
def button_done(self, cr, uid, ids, context={}):
def button_done(self, cr, uid, ids, context=None):
if context is None:
context = {}
wf_service = netsvc.LocalService("workflow")
res = self.write(cr, uid, ids, {'state': 'done'})
for line in self.browse(cr, uid, ids, context):
for line in self.browse(cr, uid, ids, context=context):
wf_service.trg_write(uid, 'sale.order', line.order_id.id, cr)
return res
@ -926,11 +980,13 @@ class sale_order_line(osv.osv):
pass
return {'value': value}
def copy_data(self, cr, uid, id, default=None, context={}):
def copy_data(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if not default:
default = {}
default.update({'state': 'draft', 'move_ids': [], 'invoiced': False, 'invoice_lines': []})
return super(sale_order_line, self).copy_data(cr, uid, id, default, context)
return super(sale_order_line, self).copy_data(cr, uid, id, default, context=context)
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
@ -961,7 +1017,7 @@ class sale_order_line(osv.osv):
if packaging:
default_uom = product_obj.uom_id and product_obj.uom_id.id
pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context)
pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context=context)
q = product_uom_obj._compute_qty(cr, uid, uom, pack.qty, default_uom)
# qty = qty - qty % q + q
if qty and (q and not (qty % q) == 0):
@ -1070,7 +1126,9 @@ class sale_order_line(osv.osv):
res['value']['price_unit'] = 0.0
return res
def unlink(self, cr, uid, ids, context={}):
def unlink(self, cr, uid, ids, context=None):
if context is None:
context = {}
"""Allows to delete sale order lines in draft,cancel states"""
for rec in self.browse(cr, uid, ids, context=context):
if rec.state not in ['draft', 'cancel']:
@ -1111,6 +1169,8 @@ class sale_config_picking_policy(osv.osv_memory):
}
def execute(self, cr, uid, ids, context=None):
if context is None:
context = {}
for o in self.browse(cr, uid, ids, context=context):
ir_values_obj = self.pool.get('ir.values')
ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], o.picking_policy)
@ -1119,13 +1179,13 @@ class sale_config_picking_policy(osv.osv_memory):
if o.step == 'one':
md = self.pool.get('ir.model.data')
group_id = md._get_id(cr, uid, 'base', 'group_no_one')
group_id = md.browse(cr, uid, group_id, context).res_id
group_id = md.browse(cr, uid, group_id, context=context).res_id
menu_id = md._get_id(cr, uid, 'stock', 'menu_action_picking_tree_delivery')
menu_id = md.browse(cr, uid, menu_id, context).res_id
menu_id = md.browse(cr, uid, menu_id, context=context).res_id
self.pool.get('ir.ui.menu').write(cr, uid, [menu_id], {'groups_id': [(6, 0, [group_id])]})
location_id = md._get_id(cr, uid, 'stock', 'stock_location_output')
location_id = md.browse(cr, uid, location_id, context).res_id
location_id = md.browse(cr, uid, location_id, context=context).res_id
self.pool.get('stock.location').write(cr, uid, [location_id], {'chained_auto_packing': 'transparent'})
sale_config_picking_policy()