[MERGE] branch with fixes of mrp_repair accordingly to new WMS
bzr revid: qdp-launchpad@openerp.com-20140127165906-zepvmq8l7ua32673
This commit is contained in:
commit
be17f492f9
|
@ -19,13 +19,11 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.osv import fields,osv
|
from openerp.osv import fields, osv
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
import openerp.addons.decimal_precision as dp
|
import openerp.addons.decimal_precision as dp
|
||||||
|
|
||||||
# TODO: replace move_id by quant_id everywhere
|
|
||||||
|
|
||||||
class mrp_repair(osv.osv):
|
class mrp_repair(osv.osv):
|
||||||
_name = 'mrp.repair'
|
_name = 'mrp.repair'
|
||||||
|
@ -77,7 +75,7 @@ class mrp_repair(osv.osv):
|
||||||
val += c['amount']
|
val += c['amount']
|
||||||
for line in repair.fees_lines:
|
for line in repair.fees_lines:
|
||||||
if line.to_invoice:
|
if line.to_invoice:
|
||||||
tax_calculate = tax_obj.compute_all(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, line.product_id, repair.partner_id)
|
tax_calculate = tax_obj.compute_all(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, line.product_id, repair.partner_id)
|
||||||
for c in tax_calculate['taxes']:
|
for c in tax_calculate['taxes']:
|
||||||
val += c['amount']
|
val += c['amount']
|
||||||
res[repair.id] = cur_obj.round(cr, uid, cur, val)
|
res[repair.id] = cur_obj.round(cr, uid, cur, val)
|
||||||
|
@ -116,20 +114,23 @@ class mrp_repair(osv.osv):
|
||||||
return result.keys()
|
return result.keys()
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Repair Reference',size=24, required=True, states={'confirmed':[('readonly',True)]}),
|
'name': fields.char('Repair Reference', size=24, required=True, states={'confirmed': [('readonly', True)]}),
|
||||||
'product_id': fields.many2one('product.product', string='Product to Repair', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
'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='Choose partner for whom the order will be invoiced and delivered.', states={'confirmed':[('readonly',True)]}),
|
'product_qty': fields.float('Product Quantity', digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||||
'address_id': fields.many2one('res.partner', 'Delivery Address', domain="[('parent_id','=',partner_id)]", states={'confirmed':[('readonly',True)]}),
|
required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
|
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
|
'partner_id': fields.many2one('res.partner', 'Partner', select=True, help='Choose partner for whom the order will be invoiced and delivered.', states={'confirmed': [('readonly', True)]}),
|
||||||
|
'address_id': fields.many2one('res.partner', 'Delivery Address', domain="[('parent_id','=',partner_id)]", states={'confirmed': [('readonly', True)]}),
|
||||||
'default_address_id': fields.function(_get_default_address, type="many2one", relation="res.partner"),
|
'default_address_id': fields.function(_get_default_address, type="many2one", relation="res.partner"),
|
||||||
'state': fields.selection([
|
'state': fields.selection([
|
||||||
('draft','Quotation'),
|
('draft', 'Quotation'),
|
||||||
('cancel','Cancelled'),
|
('cancel', 'Cancelled'),
|
||||||
('confirmed','Confirmed'),
|
('confirmed', 'Confirmed'),
|
||||||
('under_repair','Under Repair'),
|
('under_repair', 'Under Repair'),
|
||||||
('ready','Ready to Repair'),
|
('ready', 'Ready to Repair'),
|
||||||
('2binvoiced','To be Invoiced'),
|
('2binvoiced', 'To be Invoiced'),
|
||||||
('invoice_except','Invoice Exception'),
|
('invoice_except', 'Invoice Exception'),
|
||||||
('done','Repaired')
|
('done', 'Repaired')
|
||||||
], 'Status', readonly=True, track_visibility='onchange',
|
], 'Status', readonly=True, track_visibility='onchange',
|
||||||
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed repair order. \
|
help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed repair order. \
|
||||||
\n* The \'Confirmed\' status is used when a user confirms the repair order. \
|
\n* The \'Confirmed\' status is used when a user confirms the repair order. \
|
||||||
|
@ -137,27 +138,25 @@ class mrp_repair(osv.osv):
|
||||||
\n* The \'To be Invoiced\' status is used to generate the invoice before or after repairing done. \
|
\n* The \'To be Invoiced\' status is used to generate the invoice before or after repairing done. \
|
||||||
\n* The \'Done\' status is set when repairing is completed.\
|
\n* The \'Done\' status is set when repairing is completed.\
|
||||||
\n* The \'Cancelled\' status is used when user cancel repair order.'),
|
\n* The \'Cancelled\' status is used when user cancel repair order.'),
|
||||||
'location_id': fields.many2one('stock.location', 'Current Location', select=True, readonly=True, states={'draft':[('readonly',False)], 'confirmed':[('readonly',True)]}),
|
'location_id': fields.many2one('stock.location', 'Current Location', select=True, required=True, readonly=True, states={'draft': [('readonly', False)], 'confirmed': [('readonly', True)]}),
|
||||||
'location_dest_id': fields.many2one('stock.location', 'Delivery Location', readonly=True, states={'draft':[('readonly',False)], 'confirmed':[('readonly',True)]}),
|
'location_dest_id': fields.many2one('stock.location', 'Delivery Location', readonly=True, required=True, states={'draft': [('readonly', False)], 'confirmed': [('readonly', True)]}),
|
||||||
'move_id': fields.many2one('stock.move', 'Move',required=True, domain="[('product_id','=',product_id)]", readonly=True, states={'draft':[('readonly',False)]}),
|
'lot_id': fields.many2one('stock.production.lot', 'Repaired Lot', domain="[('product_id','=', product_id)]", help="Products repaired are all belonging to this lot"),
|
||||||
'guarantee_limit': fields.date('Warranty Expiration', help="The warranty expiration limit is computed as: last move date + warranty defined on selected product. If the current date is below the warranty expiration limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards.", states={'confirmed':[('readonly',True)]}),
|
'guarantee_limit': fields.date('Warranty Expiration', help="The warranty expiration limit is computed as: last move date + warranty defined on selected product. If the current date is below the warranty expiration limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards.", states={'confirmed': [('readonly', True)]}),
|
||||||
'operations' : fields.one2many('mrp.repair.line', 'repair_id', 'Operation Lines', readonly=True, states={'draft':[('readonly',False)]}),
|
'operations': fields.one2many('mrp.repair.line', 'repair_id', 'Operation Lines', readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', help='Pricelist of the selected partner.'),
|
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', help='Pricelist of the selected partner.'),
|
||||||
'partner_invoice_id':fields.many2one('res.partner', 'Invoicing Address'),
|
'partner_invoice_id': fields.many2one('res.partner', 'Invoicing Address'),
|
||||||
'invoice_method':fields.selection([
|
'invoice_method': fields.selection([
|
||||||
("none","No Invoice"),
|
("none", "No Invoice"),
|
||||||
("b4repair","Before Repair"),
|
("b4repair", "Before Repair"),
|
||||||
("after_repair","After Repair")
|
("after_repair", "After Repair")
|
||||||
], "Invoice Method",
|
], "Invoice Method",
|
||||||
select=True, required=True, states={'draft':[('readonly',False)]}, readonly=True, help='Selecting \'Before Repair\' or \'After Repair\' will allow you to generate invoice before or after the repair is done respectively. \'No invoice\' means you don\'t want to generate invoice for this repair order.'),
|
select=True, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='Selecting \'Before Repair\' or \'After Repair\' will allow you to generate invoice before or after the repair is done respectively. \'No invoice\' means you don\'t want to generate invoice for this repair order.'),
|
||||||
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
|
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True, track_visibility="onchange"),
|
||||||
'picking_id': fields.many2one('stock.picking', 'Picking',readonly=True),
|
'move_id': fields.many2one('stock.move', 'Move', readonly=True, help="Move created by the repair order", track_visibility="onchange"),
|
||||||
'fees_lines': fields.one2many('mrp.repair.fee', 'repair_id', 'Fees Lines', readonly=True, states={'draft':[('readonly',False)]}),
|
'fees_lines': fields.one2many('mrp.repair.fee', 'repair_id', 'Fees Lines', readonly=True, states={'draft': [('readonly', False)]}),
|
||||||
'internal_notes': fields.text('Internal Notes'),
|
'internal_notes': fields.text('Internal Notes'),
|
||||||
'quotation_notes': fields.text('Quotation Notes'),
|
'quotation_notes': fields.text('Quotation Notes'),
|
||||||
'company_id': fields.many2one('res.company', 'Company'),
|
'company_id': fields.many2one('res.company', 'Company'),
|
||||||
'deliver_bool': fields.boolean('Deliver', help="Check this box if you want to manage the delivery once the product is repaired and create a picking with selected product. Note that you can select the locations in the Info tab, if you have the extended view.", states={'confirmed':[('readonly',True)]}),
|
|
||||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type'),
|
|
||||||
'invoiced': fields.boolean('Invoiced', readonly=True),
|
'invoiced': fields.boolean('Invoiced', readonly=True),
|
||||||
'repaired': fields.boolean('Repaired', readonly=True),
|
'repaired': fields.boolean('Repaired', readonly=True),
|
||||||
'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount',
|
'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount',
|
||||||
|
@ -177,24 +176,36 @@ class mrp_repair(osv.osv):
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _default_stock_location(self, cr, uid, context=None):
|
||||||
|
try:
|
||||||
|
warehouse = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'warehouse0')
|
||||||
|
return warehouse.lot_stock_id.id
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'state': lambda *a: 'draft',
|
'state': lambda *a: 'draft',
|
||||||
'deliver_bool': lambda *a: True,
|
|
||||||
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'mrp.repair'),
|
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'mrp.repair'),
|
||||||
'invoice_method': lambda *a: 'none',
|
'invoice_method': lambda *a: 'none',
|
||||||
'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.repair', context=context),
|
'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.repair', context=context),
|
||||||
'pricelist_id': lambda self, cr, uid,context : self.pool.get('product.pricelist').search(cr, uid, [('type','=','sale')])[0]
|
'pricelist_id': lambda self, cr, uid, context: self.pool.get('product.pricelist').search(cr, uid, [('type', '=', 'sale')])[0],
|
||||||
|
'product_qty': 1.0,
|
||||||
|
'location_id': _default_stock_location,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sql_constraints = [
|
||||||
|
('name', 'unique (name)', 'The name of the Repair Order must be unique!'),
|
||||||
|
]
|
||||||
|
|
||||||
def copy(self, cr, uid, id, default=None, context=None):
|
def copy(self, cr, uid, id, default=None, context=None):
|
||||||
if not default:
|
if not default:
|
||||||
default = {}
|
default = {}
|
||||||
default.update({
|
default.update({
|
||||||
'state':'draft',
|
'state': 'draft',
|
||||||
'repaired':False,
|
'repaired': False,
|
||||||
'invoiced':False,
|
'invoiced': False,
|
||||||
'invoice_id': False,
|
'invoice_id': False,
|
||||||
'picking_id': False,
|
'move_id': False,
|
||||||
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.repair'),
|
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.repair'),
|
||||||
})
|
})
|
||||||
return super(mrp_repair, self).copy(cr, uid, id, default, context)
|
return super(mrp_repair, self).copy(cr, uid, id, default, context)
|
||||||
|
@ -204,39 +215,31 @@ class mrp_repair(osv.osv):
|
||||||
@param product_id: Changed product
|
@param product_id: Changed product
|
||||||
@return: Dictionary of values.
|
@return: Dictionary of values.
|
||||||
"""
|
"""
|
||||||
|
product = False
|
||||||
|
if product_id:
|
||||||
|
product = self.pool.get("product.product").browse(cr, uid, product_id)
|
||||||
return {'value': {
|
return {'value': {
|
||||||
'move_id': False,
|
'guarantee_limit': False,
|
||||||
'guarantee_limit' :False,
|
'lot_id': False,
|
||||||
'location_id': False,
|
'product_uom': product and product.uom_id.id or False,
|
||||||
'location_dest_id': False,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_move_id(self, cr, uid, ids, prod_id=False, move_id=False):
|
def onchange_product_uom(self, cr, uid, ids, product_id, product_uom, context=None):
|
||||||
""" On change of move id sets values of guarantee limit, source location,
|
res = {'value': {}}
|
||||||
destination location, partner and partner address.
|
if not product_uom or not product_id:
|
||||||
@param prod_id: Id of product in current record.
|
return res
|
||||||
@param move_id: Changed move.
|
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||||
@return: Dictionary of values.
|
uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
|
||||||
|
if uom.category_id.id != product.uom_id.category_id.id:
|
||||||
|
res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
|
||||||
|
res['value'].update({'product_uom': product.uom_id.id})
|
||||||
|
return res
|
||||||
|
|
||||||
|
def onchange_location_id(self, cr, uid, ids, location_id=None):
|
||||||
|
""" On change of location
|
||||||
"""
|
"""
|
||||||
data = {}
|
return {'value': {'location_dest_id': location_id}}
|
||||||
data['value'] = {'guarantee_limit': False, 'location_id': False, 'partner_id': False}
|
|
||||||
if not prod_id:
|
|
||||||
return data
|
|
||||||
if move_id:
|
|
||||||
move = self.pool.get('stock.move').browse(cr, uid, move_id)
|
|
||||||
product = self.pool.get('product.product').browse(cr, uid, prod_id)
|
|
||||||
limit = datetime.strptime(move.date_expected, '%Y-%m-%d %H:%M:%S') + relativedelta(months=int(product.warranty))
|
|
||||||
data['value']['guarantee_limit'] = limit.strftime('%Y-%m-%d')
|
|
||||||
data['value']['location_id'] = move.location_dest_id.id
|
|
||||||
data['value']['location_dest_id'] = move.location_dest_id.id
|
|
||||||
if move.partner_id:
|
|
||||||
data['value']['partner_id'] = move.partner_id.id
|
|
||||||
else:
|
|
||||||
data['value']['partner_id'] = False
|
|
||||||
d = self.onchange_partner_id(cr, uid, ids, data['value']['partner_id'], data['value']['partner_id'])
|
|
||||||
data['value'].update(d['value'])
|
|
||||||
return data
|
|
||||||
|
|
||||||
def button_dummy(self, cr, uid, ids, context=None):
|
def button_dummy(self, cr, uid, ids, context=None):
|
||||||
return True
|
return True
|
||||||
|
@ -254,7 +257,7 @@ class mrp_repair(osv.osv):
|
||||||
return {'value': {
|
return {'value': {
|
||||||
'address_id': False,
|
'address_id': False,
|
||||||
'partner_invoice_id': False,
|
'partner_invoice_id': False,
|
||||||
'pricelist_id': pricelist_obj.search(cr, uid, [('type','=','sale')])[0]
|
'pricelist_id': pricelist_obj.search(cr, uid, [('type', '=', 'sale')])[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr = part_obj.address_get(cr, uid, [part], ['delivery', 'invoice', 'default'])
|
addr = part_obj.address_get(cr, uid, [part], ['delivery', 'invoice', 'default'])
|
||||||
|
@ -267,40 +270,6 @@ class mrp_repair(osv.osv):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_lot_id(self, cr, uid, ids, lot, product_id):
|
|
||||||
""" On change of Serial Number sets the values of source location,
|
|
||||||
destination location, move and guarantee limit.
|
|
||||||
@param lot: Changed id of Serial Number.
|
|
||||||
@param product_id: Product id from current record.
|
|
||||||
@return: Dictionary of values.
|
|
||||||
"""
|
|
||||||
move_obj = self.pool.get('stock.move')
|
|
||||||
data = {}
|
|
||||||
data['value'] = {
|
|
||||||
'location_id': False,
|
|
||||||
'location_dest_id': False,
|
|
||||||
'move_id': False,
|
|
||||||
'guarantee_limit': False
|
|
||||||
}
|
|
||||||
|
|
||||||
if not lot:
|
|
||||||
return data
|
|
||||||
|
|
||||||
if not len(move_ids):
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_last_move(lst_move):
|
|
||||||
while lst_move.move_dest_id and lst_move.move_dest_id.state == 'done':
|
|
||||||
lst_move = lst_move.move_dest_id
|
|
||||||
return lst_move
|
|
||||||
|
|
||||||
move_id = move_ids[0]
|
|
||||||
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):
|
def action_cancel_draft(self, cr, uid, ids, *args):
|
||||||
""" Cancels repair order when it is in 'Draft' state.
|
""" Cancels repair order when it is in 'Draft' state.
|
||||||
@param *arg: Arguments
|
@param *arg: Arguments
|
||||||
|
@ -311,9 +280,8 @@ class mrp_repair(osv.osv):
|
||||||
mrp_line_obj = self.pool.get('mrp.repair.line')
|
mrp_line_obj = self.pool.get('mrp.repair.line')
|
||||||
for repair in self.browse(cr, uid, ids):
|
for repair in self.browse(cr, uid, ids):
|
||||||
mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'draft'})
|
mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'draft'})
|
||||||
self.write(cr, uid, ids, {'state':'draft'})
|
self.write(cr, uid, ids, {'state': 'draft'})
|
||||||
self.create_workflow(cr, uid, ids)
|
return self.create_workflow(cr, uid, ids)
|
||||||
return True
|
|
||||||
|
|
||||||
def action_confirm(self, cr, uid, ids, *args):
|
def action_confirm(self, cr, uid, ids, *args):
|
||||||
""" Repair order state is set to 'To be invoiced' when invoice method
|
""" Repair order state is set to 'To be invoiced' when invoice method
|
||||||
|
@ -342,13 +310,13 @@ class mrp_repair(osv.osv):
|
||||||
if not repair.invoiced:
|
if not repair.invoiced:
|
||||||
mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'cancel'}, context=context)
|
mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'cancel'}, context=context)
|
||||||
else:
|
else:
|
||||||
raise osv.except_osv(_('Warning!'),_('Repair order is already invoiced.'))
|
raise osv.except_osv(_('Warning!'), _('Repair order is already invoiced.'))
|
||||||
return self.write(cr,uid,ids,{'state':'cancel'})
|
return self.write(cr, uid, ids, {'state': 'cancel'})
|
||||||
|
|
||||||
def wkf_invoice_create(self, cr, uid, ids, *args):
|
def wkf_invoice_create(self, cr, uid, ids, *args):
|
||||||
self.action_invoice_create(cr, uid, ids)
|
self.action_invoice_create(cr, uid, ids)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_invoice_create(self, cr, uid, ids, group=False, context=None):
|
def action_invoice_create(self, cr, uid, ids, group=False, context=None):
|
||||||
""" Creates invoice(s) for repair order.
|
""" Creates invoice(s) for repair order.
|
||||||
@param group: It is set to true when group invoice is to be generated.
|
@param group: It is set to true when group invoice is to be generated.
|
||||||
|
@ -362,28 +330,28 @@ class mrp_repair(osv.osv):
|
||||||
repair_fee_obj = self.pool.get('mrp.repair.fee')
|
repair_fee_obj = self.pool.get('mrp.repair.fee')
|
||||||
for repair in self.browse(cr, uid, ids, context=context):
|
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:
|
if repair.state in ('draft', 'cancel') or repair.invoice_id:
|
||||||
continue
|
continue
|
||||||
if not (repair.partner_id.id and repair.partner_invoice_id.id):
|
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!'))
|
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 (repair.invoice_method != 'none'):
|
||||||
if group and repair.partner_invoice_id.id in invoices_group:
|
if group and repair.partner_invoice_id.id in invoices_group:
|
||||||
inv_id = invoices_group[repair.partner_invoice_id.id]
|
inv_id = invoices_group[repair.partner_invoice_id.id]
|
||||||
invoice = inv_obj.browse(cr, uid, inv_id)
|
invoice = inv_obj.browse(cr, uid, inv_id)
|
||||||
invoice_vals = {
|
invoice_vals = {
|
||||||
'name': invoice.name +', '+repair.name,
|
'name': invoice.name + ', ' + repair.name,
|
||||||
'origin': invoice.origin+', '+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 ''),
|
'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''),
|
||||||
}
|
}
|
||||||
inv_obj.write(cr, uid, [inv_id], invoice_vals, context=context)
|
inv_obj.write(cr, uid, [inv_id], invoice_vals, context=context)
|
||||||
else:
|
else:
|
||||||
if not repair.partner_id.property_account_receivable:
|
if not repair.partner_id.property_account_receivable:
|
||||||
raise osv.except_osv(_('Error!'), _('No account defined for partner "%s".') % repair.partner_id.name )
|
raise osv.except_osv(_('Error!'), _('No account defined for partner "%s".') % repair.partner_id.name)
|
||||||
account_id = repair.partner_id.property_account_receivable.id
|
account_id = repair.partner_id.property_account_receivable.id
|
||||||
inv = {
|
inv = {
|
||||||
'name': repair.name,
|
'name': repair.name,
|
||||||
'origin':repair.name,
|
'origin': repair.name,
|
||||||
'type': 'out_invoice',
|
'type': 'out_invoice',
|
||||||
'account_id': account_id,
|
'account_id': account_id,
|
||||||
'partner_id': repair.partner_id.id,
|
'partner_id': repair.partner_id.id,
|
||||||
|
@ -396,7 +364,7 @@ class mrp_repair(osv.osv):
|
||||||
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:
|
for operation in repair.operations:
|
||||||
if operation.to_invoice == True:
|
if operation.to_invoice:
|
||||||
if group:
|
if group:
|
||||||
name = repair.name + '-' + operation.name
|
name = repair.name + '-' + operation.name
|
||||||
else:
|
else:
|
||||||
|
@ -407,7 +375,7 @@ class mrp_repair(osv.osv):
|
||||||
elif operation.product_id.categ_id.property_account_income_categ:
|
elif operation.product_id.categ_id.property_account_income_categ:
|
||||||
account_id = operation.product_id.categ_id.property_account_income_categ.id
|
account_id = operation.product_id.categ_id.property_account_income_categ.id
|
||||||
else:
|
else:
|
||||||
raise osv.except_osv(_('Error!'), _('No account defined for product "%s".') % operation.product_id.name )
|
raise osv.except_osv(_('Error!'), _('No account defined for product "%s".') % operation.product_id.name)
|
||||||
|
|
||||||
invoice_line_id = inv_line_obj.create(cr, uid, {
|
invoice_line_id = inv_line_obj.create(cr, uid, {
|
||||||
'invoice_id': inv_id,
|
'invoice_id': inv_id,
|
||||||
|
@ -415,15 +383,15 @@ class mrp_repair(osv.osv):
|
||||||
'origin': repair.name,
|
'origin': repair.name,
|
||||||
'account_id': account_id,
|
'account_id': account_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])],
|
'invoice_line_tax_id': [(6, 0, [x.id for x in operation.tax_id])],
|
||||||
'uos_id': operation.product_uom.id,
|
'uos_id': operation.product_uom.id,
|
||||||
'price_unit': operation.price_unit,
|
'price_unit': operation.price_unit,
|
||||||
'price_subtotal': operation.product_uom_qty*operation.price_unit,
|
'price_subtotal': operation.product_uom_qty * operation.price_unit,
|
||||||
'product_id': operation.product_id and operation.product_id.id or False
|
'product_id': operation.product_id and operation.product_id.id or False
|
||||||
})
|
})
|
||||||
repair_line_obj.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:
|
for fee in repair.fees_lines:
|
||||||
if fee.to_invoice == True:
|
if fee.to_invoice:
|
||||||
if group:
|
if group:
|
||||||
name = repair.name + '-' + fee.name
|
name = repair.name + '-' + fee.name
|
||||||
else:
|
else:
|
||||||
|
@ -444,11 +412,11 @@ class mrp_repair(osv.osv):
|
||||||
'origin': repair.name,
|
'origin': repair.name,
|
||||||
'account_id': account_id,
|
'account_id': account_id,
|
||||||
'quantity': fee.product_uom_qty,
|
'quantity': fee.product_uom_qty,
|
||||||
'invoice_line_tax_id': [(6,0,[x.id for x in fee.tax_id])],
|
'invoice_line_tax_id': [(6, 0, [x.id for x in fee.tax_id])],
|
||||||
'uos_id': fee.product_uom.id,
|
'uos_id': fee.product_uom.id,
|
||||||
'product_id': fee.product_id and fee.product_id.id or False,
|
'product_id': fee.product_id and fee.product_id.id or False,
|
||||||
'price_unit': fee.price_unit,
|
'price_unit': fee.price_unit,
|
||||||
'price_subtotal': fee.product_uom_qty*fee.price_unit
|
'price_subtotal': fee.product_uom_qty * fee.price_unit
|
||||||
})
|
})
|
||||||
repair_fee_obj.write(cr, uid, [fee.id], {'invoiced': True, 'invoice_line_id': invoice_fee_id})
|
repair_fee_obj.write(cr, uid, [fee.id], {'invoiced': True, 'invoice_line_id': invoice_fee_id})
|
||||||
res[repair.id] = inv_id
|
res[repair.id] = inv_id
|
||||||
|
@ -483,9 +451,9 @@ class mrp_repair(osv.osv):
|
||||||
for order in self.browse(cr, uid, ids, context=context):
|
for order in self.browse(cr, uid, ids, context=context):
|
||||||
val = {}
|
val = {}
|
||||||
val['repaired'] = True
|
val['repaired'] = True
|
||||||
if (not order.invoiced and order.invoice_method=='after_repair'):
|
if (not order.invoiced and order.invoice_method == 'after_repair'):
|
||||||
val['state'] = '2binvoiced'
|
val['state'] = '2binvoiced'
|
||||||
elif (not order.invoiced and order.invoice_method=='b4repair'):
|
elif (not order.invoiced and order.invoice_method == 'b4repair'):
|
||||||
val['state'] = 'ready'
|
val['state'] = 'ready'
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
@ -497,18 +465,19 @@ class mrp_repair(osv.osv):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_repair_done(self, cr, uid, ids, context=None):
|
def action_repair_done(self, cr, uid, ids, context=None):
|
||||||
""" Creates stock move and picking for repair order.
|
""" Creates stock move for operation and stock move for final product of repair order.
|
||||||
@return: Picking ids.
|
@return: Move ids of final products
|
||||||
"""
|
"""
|
||||||
res = {}
|
res = {}
|
||||||
move_obj = self.pool.get('stock.move')
|
move_obj = self.pool.get('stock.move')
|
||||||
repair_line_obj = self.pool.get('mrp.repair.line')
|
repair_line_obj = self.pool.get('mrp.repair.line')
|
||||||
pick_obj = self.pool.get('stock.picking')
|
|
||||||
for repair in self.browse(cr, uid, ids, context=context):
|
for repair in self.browse(cr, uid, ids, context=context):
|
||||||
|
move_ids = []
|
||||||
for move in repair.operations:
|
for move in repair.operations:
|
||||||
move_id = move_obj.create(cr, uid, {
|
move_id = move_obj.create(cr, uid, {
|
||||||
'name': move.name,
|
'name': move.name,
|
||||||
'product_id': move.product_id.id,
|
'product_id': move.product_id.id,
|
||||||
|
'restrict_lot_id': move.lot_id.id,
|
||||||
'product_uom_qty': move.product_uom_qty,
|
'product_uom_qty': move.product_uom_qty,
|
||||||
'product_uom': move.product_uom.id,
|
'product_uom': move.product_uom.id,
|
||||||
'partner_id': repair.address_id and repair.address_id.id or False,
|
'partner_id': repair.address_id and repair.address_id.id or False,
|
||||||
|
@ -516,37 +485,22 @@ class mrp_repair(osv.osv):
|
||||||
'location_dest_id': move.location_dest_id.id,
|
'location_dest_id': move.location_dest_id.id,
|
||||||
'state': 'assigned',
|
'state': 'assigned',
|
||||||
})
|
})
|
||||||
move_obj.action_done(cr, uid, [move_id], context=context)
|
move_ids.append(move_id)
|
||||||
repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id, 'state': 'done'}, context=context)
|
repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id, 'state': 'done'}, context=context)
|
||||||
if repair.deliver_bool:
|
move_id = move_obj.create(cr, uid, {
|
||||||
if not repair.picking_type_id:
|
'name': repair.name,
|
||||||
raise osv.except_osv(_('Warning!'), _('No picking type set.'))
|
'product_id': repair.product_id.id,
|
||||||
pick_name = self.pool.get('ir.sequence').get_id(cr, uid, repair.picking_type_id.sequence_id.id, 'id', context=context)
|
'product_uom': repair.product_uom.id or repair.product_id.uom_id.id,
|
||||||
picking = pick_obj.create(cr, uid, {
|
'product_qty': repair.product_qty,
|
||||||
'name': pick_name,
|
'partner_id': repair.address_id and repair.address_id.id or False,
|
||||||
'origin': repair.name,
|
'location_id': repair.location_id.id,
|
||||||
'state': 'draft',
|
'location_dest_id': repair.location_dest_id.id,
|
||||||
'move_type': 'one',
|
'restrict_lot_id': repair.lot_id.id,
|
||||||
'partner_id': repair.address_id and repair.address_id.id or False,
|
})
|
||||||
'note': repair.internal_notes,
|
move_ids.append(move_id)
|
||||||
'invoice_state': 'none',
|
move_obj.action_done(cr, uid, move_ids, context=context)
|
||||||
'picking_type_id': repair.picking_type_id.id,
|
self.write(cr, uid, [repair.id], {'state': 'done', 'move_id': move_id}, context=context)
|
||||||
})
|
res[repair.id] = move_id
|
||||||
move_id = move_obj.create(cr, uid, {
|
|
||||||
'name': repair.name,
|
|
||||||
'picking_id': picking,
|
|
||||||
'product_id': repair.product_id.id,
|
|
||||||
'product_uom': repair.product_id.uom_id.id,
|
|
||||||
'partner_id': repair.address_id and repair.address_id.id or False,
|
|
||||||
'location_id': repair.location_id.id,
|
|
||||||
'location_dest_id': repair.location_dest_id.id,
|
|
||||||
'state': 'assigned',
|
|
||||||
})
|
|
||||||
pick_obj.signal_button_confirm(cr, uid, [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'})
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@ -580,24 +534,24 @@ class ProductChangeMixin(object):
|
||||||
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False
|
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False
|
||||||
if not pricelist:
|
if not pricelist:
|
||||||
warning = {
|
warning = {
|
||||||
'title':'No Pricelist!',
|
'title': _('No Pricelist!'),
|
||||||
'message':
|
'message':
|
||||||
'You have to select a pricelist in the Repair form !\n'
|
_('You have to select a pricelist in the Repair form !\n'
|
||||||
'Please set one before choosing a product.'
|
'Please set one before choosing a product.')
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
|
price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
|
||||||
product, product_uom_qty, partner_id, {'uom': uom,})[pricelist]
|
product, product_uom_qty, partner_id, {'uom': uom})[pricelist]
|
||||||
|
|
||||||
if price is False:
|
if price is False:
|
||||||
warning = {
|
warning = {
|
||||||
'title':'No valid pricelist line found !',
|
'title': _('No valid pricelist line found !'),
|
||||||
'message':
|
'message':
|
||||||
"Couldn't find a pricelist line matching this product and quantity.\n"
|
_("Couldn't find a pricelist line matching this product and quantity.\n"
|
||||||
"You have to change either the product, the quantity or the pricelist."
|
"You have to change either the product, the quantity or the pricelist.")
|
||||||
}
|
}
|
||||||
else:
|
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}
|
return {'value': result, 'warning': warning}
|
||||||
|
|
||||||
|
@ -607,8 +561,9 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
|
||||||
_description = 'Repair Line'
|
_description = 'Repair Line'
|
||||||
|
|
||||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||||
if not default: default = {}
|
if not default:
|
||||||
default.update( {'invoice_line_id': False, 'move_id': False, 'invoiced': False, 'state': 'draft'})
|
default = {}
|
||||||
|
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)
|
return super(mrp_repair_line, self).copy_data(cr, uid, id, default, context)
|
||||||
|
|
||||||
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
|
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
|
@ -618,7 +573,7 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
|
||||||
@return: Dictionary of values.
|
@return: Dictionary of values.
|
||||||
"""
|
"""
|
||||||
res = {}
|
res = {}
|
||||||
cur_obj=self.pool.get('res.currency')
|
cur_obj = self.pool.get('res.currency')
|
||||||
for line in self.browse(cr, uid, ids, context=context):
|
for line in self.browse(cr, uid, ids, context=context):
|
||||||
res[line.id] = line.to_invoice and line.price_unit * line.product_uom_qty or 0
|
res[line.id] = line.to_invoice and line.price_unit * line.product_uom_qty or 0
|
||||||
cur = line.repair_id.pricelist_id.currency_id
|
cur = line.repair_id.pricelist_id.currency_id
|
||||||
|
@ -626,34 +581,35 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name' : fields.char('Description',size=64,required=True),
|
'name': fields.char('Description', size=64, required=True),
|
||||||
'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference',ondelete='cascade', select=True),
|
'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', ondelete='cascade', select=True),
|
||||||
'type': fields.selection([('add','Add'),('remove','Remove')],'Type', required=True),
|
'type': fields.selection([('add', 'Add'), ('remove', 'Remove')], 'Type', required=True),
|
||||||
'to_invoice': fields.boolean('To Invoice'),
|
'to_invoice': fields.boolean('To Invoice'),
|
||||||
'product_id': fields.many2one('product.product', 'Product', required=True),
|
'product_id': fields.many2one('product.product', 'Product', required=True),
|
||||||
'invoiced': fields.boolean('Invoiced',readonly=True),
|
'invoiced': fields.boolean('Invoiced', readonly=True),
|
||||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
|
'price_unit': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Product Price')),
|
||||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Account')),
|
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute=dp.get_precision('Account')),
|
||||||
'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes'),
|
'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes'),
|
||||||
'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True),
|
'product_uom_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
|
||||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||||
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
||||||
'location_id': fields.many2one('stock.location', 'Source Location', required=True, select=True),
|
'location_id': fields.many2one('stock.location', 'Source Location', required=True, select=True),
|
||||||
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, select=True),
|
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, select=True),
|
||||||
'move_id': fields.many2one('stock.move', 'Inventory Move', readonly=True),
|
'move_id': fields.many2one('stock.move', 'Inventory Move', readonly=True),
|
||||||
|
'lot_id': fields.many2one('stock.production.lot', 'Lot'),
|
||||||
'state': fields.selection([
|
'state': fields.selection([
|
||||||
('draft','Draft'),
|
('draft', 'Draft'),
|
||||||
('confirmed','Confirmed'),
|
('confirmed', 'Confirmed'),
|
||||||
('done','Done'),
|
('done', 'Done'),
|
||||||
('cancel','Cancelled')], 'Status', required=True, readonly=True,
|
('cancel', 'Cancelled')], 'Status', required=True, readonly=True,
|
||||||
help=' * The \'Draft\' status is set automatically as draft when repair order in draft status. \
|
help=' * The \'Draft\' status is set automatically as draft when repair order in draft status. \
|
||||||
\n* The \'Confirmed\' status is set automatically as confirm when repair order in confirm status. \
|
\n* The \'Confirmed\' status is set automatically as confirm when repair order in confirm status. \
|
||||||
\n* The \'Done\' status is set automatically when repair order is completed.\
|
\n* The \'Done\' status is set automatically when repair order is completed.\
|
||||||
\n* The \'Cancelled\' status is set automatically when user cancel repair order.'),
|
\n* The \'Cancelled\' status is set automatically when user cancel repair order.'),
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'state': lambda *a: 'draft',
|
'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, company_id=False, context=None):
|
def onchange_operation_type(self, cr, uid, ids, type, guarantee_limit, company_id=False, context=None):
|
||||||
|
@ -670,7 +626,7 @@ class mrp_repair_line(osv.osv, ProductChangeMixin):
|
||||||
}}
|
}}
|
||||||
location_obj = self.pool.get('stock.location')
|
location_obj = self.pool.get('stock.location')
|
||||||
warehouse_obj = self.pool.get('stock.warehouse')
|
warehouse_obj = self.pool.get('stock.warehouse')
|
||||||
location_id = location_obj.search(cr, uid, [('usage','=','production')], context=context)
|
location_id = location_obj.search(cr, uid, [('usage', '=', 'production')], context=context)
|
||||||
location_id = location_id and location_id[0] or False
|
location_id = location_id and location_id[0] or False
|
||||||
|
|
||||||
if type == 'add':
|
if type == 'add':
|
||||||
|
@ -702,7 +658,8 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin):
|
||||||
_description = 'Repair Fees Line'
|
_description = 'Repair Fees Line'
|
||||||
|
|
||||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||||
if not default: default = {}
|
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)
|
return super(mrp_repair_fee, self).copy_data(cr, uid, id, default, context)
|
||||||
|
|
||||||
|
@ -722,17 +679,18 @@ class mrp_repair_fee(osv.osv, ProductChangeMixin):
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', required=True, ondelete='cascade', select=True),
|
'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', required=True, ondelete='cascade', select=True),
|
||||||
'name': fields.char('Description', size=64, select=True,required=True),
|
'name': fields.char('Description', size=64, select=True, required=True),
|
||||||
'product_id': fields.many2one('product.product', 'Product'),
|
'product_id': fields.many2one('product.product', 'Product'),
|
||||||
'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True),
|
'product_uom_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
|
||||||
'price_unit': fields.float('Unit Price', required=True),
|
'price_unit': fields.float('Unit Price', required=True),
|
||||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||||
'price_subtotal': fields.function(_amount_line, string='Subtotal',digits_compute= dp.get_precision('Account')),
|
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute=dp.get_precision('Account')),
|
||||||
'tax_id': fields.many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes'),
|
'tax_id': fields.many2many('account.tax', 'repair_fee_line_tax', 'repair_fee_line_id', 'tax_id', 'Taxes'),
|
||||||
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True),
|
||||||
'to_invoice': fields.boolean('To Invoice'),
|
'to_invoice': fields.boolean('To Invoice'),
|
||||||
'invoiced': fields.boolean('Invoiced',readonly=True),
|
'invoiced': fields.boolean('Invoiced', readonly=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'to_invoice': lambda *a: True,
|
'to_invoice': lambda *a: True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,13 @@
|
||||||
-
|
|
||||||
!record {model: stock.move, id: stock_move_pcbasicpc0}:
|
|
||||||
company_id: base.main_company
|
|
||||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
date_expected: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
location_dest_id: stock.stock_location_14
|
|
||||||
location_id: stock.stock_location_stock
|
|
||||||
name: '[PCSC234] PC Assemble SC234'
|
|
||||||
product_id: product.product_product_3
|
|
||||||
product_qty: 1.0
|
|
||||||
product_uom: product.product_uom_unit
|
|
||||||
product_uos_qty: 1.0
|
|
||||||
-
|
-
|
||||||
!record {model: mrp.repair, id: mrp_repair_rmrp1}:
|
!record {model: mrp.repair, id: mrp_repair_rmrp1}:
|
||||||
address_id: base.res_partner_address_1
|
address_id: base.res_partner_address_1
|
||||||
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
||||||
invoice_method: 'none'
|
invoice_method: 'none'
|
||||||
|
product_id: product.product_product_3
|
||||||
|
product_uom: product.product_uom_unit
|
||||||
partner_invoice_id: base.res_partner_address_1
|
partner_invoice_id: base.res_partner_address_1
|
||||||
location_dest_id: stock.stock_location_14
|
location_dest_id: stock.stock_location_14
|
||||||
location_id: stock.stock_location_14
|
location_id: stock.stock_location_stock
|
||||||
picking_type_id: stock.picking_type_out
|
|
||||||
move_id: 'stock_move_pcbasicpc0'
|
|
||||||
name: RMA00004
|
|
||||||
operations:
|
operations:
|
||||||
- location_dest_id: stock.location_production
|
- location_dest_id: stock.location_production
|
||||||
location_id: stock.stock_location_stock
|
location_id: stock.stock_location_stock
|
||||||
|
@ -39,30 +26,16 @@
|
||||||
product_uom: product.product_uom_unit
|
product_uom: product.product_uom_unit
|
||||||
price_unit: 50.0
|
price_unit: 50.0
|
||||||
partner_id: base.res_partner_9
|
partner_id: base.res_partner_9
|
||||||
product_id: product.product_product_3
|
|
||||||
-
|
|
||||||
!record {model: stock.move, id: stock.stock_move_stockmvmrp1}:
|
|
||||||
company_id: base.main_company
|
|
||||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
date_expected: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
location_dest_id: stock.stock_location_14
|
|
||||||
location_id: stock.stock_location_stock
|
|
||||||
name: '[PC-DEM] PC on Demand'
|
|
||||||
product_id: product.product_product_5
|
|
||||||
product_qty: 1.0
|
|
||||||
product_uom: product.product_uom_unit
|
|
||||||
product_uos_qty: 1.0
|
|
||||||
-
|
-
|
||||||
!record {model: mrp.repair, id: mrp_repair_rmrp0}:
|
!record {model: mrp.repair, id: mrp_repair_rmrp0}:
|
||||||
|
product_id: product.product_product_5
|
||||||
|
product_uom: product.product_uom_unit
|
||||||
address_id: base.res_partner_address_1
|
address_id: base.res_partner_address_1
|
||||||
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
||||||
invoice_method: 'after_repair'
|
invoice_method: 'after_repair'
|
||||||
partner_invoice_id: base.res_partner_address_1
|
partner_invoice_id: base.res_partner_address_1
|
||||||
location_dest_id: stock.stock_location_14
|
location_dest_id: stock.stock_location_14
|
||||||
location_id: stock.stock_location_14
|
location_id: stock.stock_location_stock
|
||||||
picking_type_id: stock.picking_type_out
|
|
||||||
move_id: 'stock.stock_move_stockmvmrp1'
|
|
||||||
name: RMA-00007
|
|
||||||
operations:
|
operations:
|
||||||
- location_dest_id: stock.location_production
|
- location_dest_id: stock.location_production
|
||||||
location_id: stock.stock_location_stock
|
location_id: stock.stock_location_stock
|
||||||
|
@ -81,30 +54,16 @@
|
||||||
product_uom: product.product_uom_unit
|
product_uom: product.product_uom_unit
|
||||||
price_unit: 50.0
|
price_unit: 50.0
|
||||||
partner_id: base.res_partner_9
|
partner_id: base.res_partner_9
|
||||||
product_id: product.product_product_5
|
|
||||||
-
|
|
||||||
!record {model: stock.move, id: stock.stock_move_stockmvmrp2}:
|
|
||||||
company_id: base.main_company
|
|
||||||
date: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
date_expected: !eval datetime.today().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
location_dest_id: stock.stock_location_14
|
|
||||||
location_id: stock.stock_location_stock
|
|
||||||
name: '[LCD15] 15” LCD Monitor'
|
|
||||||
product_id: product.product_product_6
|
|
||||||
product_qty: 1.0
|
|
||||||
product_uom: product.product_uom_unit
|
|
||||||
product_uos_qty: 1.0
|
|
||||||
-
|
-
|
||||||
!record {model: mrp.repair, id: mrp_repair_rmrp2}:
|
!record {model: mrp.repair, id: mrp_repair_rmrp2}:
|
||||||
|
product_id: product.product_product_6
|
||||||
|
product_uom: product.product_uom_unit
|
||||||
address_id: base.res_partner_address_1
|
address_id: base.res_partner_address_1
|
||||||
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
guarantee_limit: !eval datetime.today().strftime("%Y-%m-%d")
|
||||||
invoice_method: 'b4repair'
|
invoice_method: 'b4repair'
|
||||||
partner_invoice_id: base.res_partner_address_1
|
partner_invoice_id: base.res_partner_address_1
|
||||||
location_dest_id: stock.stock_location_14
|
location_dest_id: stock.stock_location_stock
|
||||||
location_id: stock.stock_location_14
|
location_id: stock.stock_location_14
|
||||||
picking_type_id: stock.picking_type_out
|
|
||||||
move_id: 'stock.stock_move_stockmvmrp2'
|
|
||||||
name: RMA-00011
|
|
||||||
operations:
|
operations:
|
||||||
- location_dest_id: stock.location_production
|
- location_dest_id: stock.location_production
|
||||||
location_id: stock.stock_location_stock
|
location_id: stock.stock_location_stock
|
||||||
|
@ -122,5 +81,4 @@
|
||||||
product_uom_qty: 1.0
|
product_uom_qty: 1.0
|
||||||
product_uom: product.product_uom_unit
|
product_uom: product.product_uom_unit
|
||||||
price_unit: 50.0
|
price_unit: 50.0
|
||||||
partner_id: base.res_partner_9
|
partner_id: base.res_partner_9
|
||||||
product_id: product.product_product_6
|
|
|
@ -9,7 +9,6 @@
|
||||||
<tree string="Repairs order" colors="gray:state in ('done','cancel');black:state not in ('done','cancel');blue:state=='draft'">
|
<tree string="Repairs order" colors="gray:state in ('done','cancel');black:state not in ('done','cancel');blue:state=='draft'">
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="product_id" />
|
<field name="product_id" />
|
||||||
<field name="move_id"/>
|
|
||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
<field name="address_id"/>
|
<field name="address_id"/>
|
||||||
<field name="location_id" groups="stock.group_locations"/>
|
<field name="location_id" groups="stock.group_locations"/>
|
||||||
|
@ -45,22 +44,25 @@
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="product_id" on_change="onchange_product_id(product_id)" domain="[('type','!=','service')]"/>
|
<field name="product_id" on_change="onchange_product_id(product_id)" domain="[('type','!=','service')]"/>
|
||||||
|
<label for="product_qty"/>
|
||||||
|
<div>
|
||||||
|
<field name="product_qty" class="oe_inline"/>
|
||||||
|
<field name="product_uom" groups="product.group_uom" on_change="onchange_product_uom(product_id, product_uom)" class="oe_inline"/>
|
||||||
|
</div>
|
||||||
|
<field name="lot_id" domain="[('product_id', '=', product_id)]" context="{'default_product_id': product_id}" groups="stock.group_tracking_lot"/>
|
||||||
<field name="partner_id" on_change="onchange_partner_id(partner_id,address_id)" attrs="{'required':[('invoice_method','!=','none')]}"/>
|
<field name="partner_id" on_change="onchange_partner_id(partner_id,address_id)" attrs="{'required':[('invoice_method','!=','none')]}"/>
|
||||||
<field name="address_id" groups="sale.group_delivery_invoice_address"/>
|
<field name="address_id" groups="sale.group_delivery_invoice_address"/>
|
||||||
<field name="move_id" on_change="onchange_move_id(product_id, move_id)" context="{'default_product_id':product_id}"/>
|
|
||||||
<field name="location_id" attrs="{'required':[('deliver_bool','=', True)]}" groups="stock.group_locations"/>
|
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
<field name="location_id" on_change="onchange_location_id(location_id)" groups="stock.group_locations" domain="[('usage', 'in', ('internal', 'customer'))]"/>
|
||||||
|
<field name="location_dest_id" groups="stock.group_locations" domain="[('usage', 'in', ('internal', 'customer'))]"/>
|
||||||
|
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||||
<field name="guarantee_limit"/>
|
<field name="guarantee_limit"/>
|
||||||
<field name="deliver_bool"/>
|
|
||||||
<field name="picking_type_id" attrs="{'invisible': [('deliver_bool','=', False)], 'required': [('deliver_bool', '=', True)]}"/>
|
|
||||||
<field name="repaired" groups="base.group_no_one"/>
|
|
||||||
<field name="invoiced" groups="base.group_no_one"/>
|
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Operations">
|
<page string="Operations">
|
||||||
<field name="operations">
|
<field name="operations" context="{'default_product_uom_qty': product_qty}">
|
||||||
<form string="Operations" version="7.0">
|
<form string="Operations" version="7.0">
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="Repair Line">
|
<page string="Repair Line">
|
||||||
|
@ -94,6 +96,7 @@
|
||||||
<field name="type" on_change="onchange_operation_type(type,parent.guarantee_limit,parent.company_id,context)"/>
|
<field name="type" on_change="onchange_operation_type(type,parent.guarantee_limit,parent.company_id,context)"/>
|
||||||
<field name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_uom,product_uom_qty, parent.partner_id)"/>
|
<field name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_uom,product_uom_qty, parent.partner_id)"/>
|
||||||
<field name='name'/>
|
<field name='name'/>
|
||||||
|
<field name="lot_id" domain="[('product_id', '=', product_id)]" context="{'default_product_id': product_id}" groups="stock.group_tracking_lot"/>
|
||||||
<field name="location_id" groups="stock.group_locations"/>
|
<field name="location_id" groups="stock.group_locations"/>
|
||||||
<field name="location_dest_id" groups="stock.group_locations"/>
|
<field name="location_dest_id" groups="stock.group_locations"/>
|
||||||
<field name="product_uom_qty" string="Quantity"/>
|
<field name="product_uom_qty" string="Quantity"/>
|
||||||
|
@ -119,13 +122,15 @@
|
||||||
<page string="Invoicing">
|
<page string="Invoicing">
|
||||||
<group col="4">
|
<group col="4">
|
||||||
<field name="invoice_method"/>
|
<field name="invoice_method"/>
|
||||||
|
<field name="invoice_id" context="{'form_view_ref': 'account.invoice_form'}"/>
|
||||||
<field name="partner_invoice_id" attrs="{'readonly':[('invoice_method','=', 'none')],'required':[('invoice_method','!=','none')]}" groups="sale.group_delivery_invoice_address"/>
|
<field name="partner_invoice_id" attrs="{'readonly':[('invoice_method','=', 'none')],'required':[('invoice_method','!=','none')]}" groups="sale.group_delivery_invoice_address"/>
|
||||||
<field
|
<field
|
||||||
name="pricelist_id" groups="product.group_sale_pricelist" context="{'product_id':product_id}"
|
name="pricelist_id" groups="product.group_sale_pricelist" context="{'product_id':product_id}"
|
||||||
attrs="{'readonly':[('invoice_method','=', 'none')]}"/>
|
attrs="{'readonly':[('invoice_method','=', 'none')]}"/>
|
||||||
</group>
|
</group>
|
||||||
<!-- <field name="invoice_id"/> -->
|
<!-- <field name="invoice_id"/> -->
|
||||||
<field name="fees_lines">
|
<separator string="Fees Lines"/>
|
||||||
|
<field name="fees_lines" attrs="{'readonly': [('invoice_method','=', 'none')]}">
|
||||||
<form string="Fees" version="7.0">
|
<form string="Fees" version="7.0">
|
||||||
<label for="name" class="oe_edit_only"/>
|
<label for="name" class="oe_edit_only"/>
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -167,15 +172,14 @@
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
<page string="Extra Info">
|
<page string="Extra Info" groups="base.group_no_one">
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="picking_id"/>
|
<field name="move_id"/>
|
||||||
<field name="invoice_id" context="{'form_view_ref': 'account.invoice_form'}"/>
|
|
||||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="location_dest_id" attrs="{'required':[('deliver_bool','=', True)]}" groups="stock.group_locations"/>
|
<field name="repaired"/>
|
||||||
|
<field name="invoiced"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
-
|
-
|
||||||
!workflow {model: mrp.repair, action: repair_confirm, ref: mrp_repair_rmrp1}
|
!workflow {model: mrp.repair, action: repair_confirm, ref: mrp_repair_rmrp1}
|
||||||
-
|
-
|
||||||
I start the repairing process by clicking on "Start Repair" button for Invoice Method 'No Invoice'.
|
I start the repairing process by clicking on "Start Repair" button for Invoice Method 'No Invoice'.
|
||||||
-
|
-
|
||||||
!workflow {model: mrp.repair, action: repair_ready, ref: mrp_repair_rmrp1}
|
!workflow {model: mrp.repair, action: repair_ready, ref: mrp_repair_rmrp1}
|
||||||
-
|
-
|
||||||
|
@ -22,9 +22,8 @@
|
||||||
!workflow {model: mrp.repair, action: action_repair_end, ref: mrp_repair_rmrp1}
|
!workflow {model: mrp.repair, action: action_repair_end, ref: mrp_repair_rmrp1}
|
||||||
-
|
-
|
||||||
I define Invoice Method 'No Invoice' option in this repair order.
|
I define Invoice Method 'No Invoice' option in this repair order.
|
||||||
So, I check that Invoice should not be created for this repair order.
|
So, I check that Invoice has not been created for this repair order.
|
||||||
-
|
-
|
||||||
!python {model: mrp.repair}: |
|
!python {model: mrp.repair}: |
|
||||||
repair_id = self.browse(cr, uid, [ref('mrp_repair_rmrp1')], context=context)[0]
|
repair_id = self.browse(cr, uid, [ref('mrp_repair_rmrp1')], context=context)[0]
|
||||||
assert not repair_id.invoice_id.id, "Invoice should not exist for this repair order"
|
assert not repair_id.invoice_id.id, "Invoice should not exist for this repair order"
|
||||||
|
|
Loading…
Reference in New Issue