How to use move method in fMBT

Best Python code snippet using fMBT_python

stock_move.py

Source:stock_move.py Github

copy

Full Screen

...957 'picking_id': self.picking_id.id,958 'price_unit': self.price_unit,959 }960 return vals961 def _create_extra_move(self):962 """ If the quantity done on a move exceeds its quantity todo, this method will create an963 extra move attached to a (potentially split) move line. If the previous condition is not964 met, it'll return an empty recordset.965 966 The rationale for the creation of an extra move is the application of a potential push967 rule that will handle the extra quantities.968 """969 extra_move = self970 rounding = self.product_uom.rounding971 # moves created after the picking is assigned do not have `product_uom_qty`, but we shouldn't create extra moves for them972 if float_compare(self.quantity_done, self.product_uom_qty, precision_rounding=rounding) > 0:973 # create the extra moves974 extra_move_quantity = float_round(975 self.quantity_done - self.product_uom_qty,976 precision_rounding=rounding,977 rounding_method='HALF-UP')978 extra_move_vals = self._prepare_extra_move_vals(extra_move_quantity)979 extra_move = self.copy(default=extra_move_vals)980 if extra_move.picking_id:981 extra_move = extra_move._action_confirm(merge_into=self)982 else:983 extra_move = extra_move._action_confirm()984 # link it to some move lines. We don't need to do it for move since they should be merged.985 if self.exists() and not self.picking_id:986 for move_line in self.move_line_ids.filtered(lambda ml: ml.qty_done):987 if float_compare(move_line.qty_done, extra_move_quantity, precision_rounding=rounding) <= 0:988 # move this move line to our extra move989 move_line.move_id = extra_move.id990 extra_move_quantity -= move_line.qty_done991 else:992 # split this move line and assign the new part to our extra move993 quantity_split = float_round(994 move_line.qty_done - extra_move_quantity,995 precision_rounding=self.product_uom.rounding,996 rounding_method='UP')997 move_line.qty_done = quantity_split998 move_line.copy(default={'move_id': extra_move.id, 'qty_done': extra_move_quantity, 'product_uom_qty': 0})999 extra_move_quantity -= extra_move_quantity1000 if extra_move_quantity == 0.0:1001 break1002 return extra_move1003 def _unreserve_initial_demand(self, new_move):1004 pass1005 def _action_done(self):1006 self.filtered(lambda move: move.state == 'draft')._action_confirm() # MRP allows scrapping draft moves1007 moves = self.exists().filtered(lambda x: x.state not in ('done', 'cancel'))1008 moves_todo = self.env['stock.move']1009 # Cancel moves where necessary ; we should do it before creating the extra moves because1010 # this operation could trigger a merge of moves.1011 for move in moves:1012 if move.quantity_done <= 0:1013 if float_compare(move.product_uom_qty, 0.0, precision_rounding=move.product_uom.rounding) == 0:1014 move._action_cancel()1015 # Create extra moves where necessary1016 for move in moves:1017 if move.state == 'cancel' or move.quantity_done <= 0:1018 continue1019 # extra move will not be merged in mrp1020 if not move.picking_id:1021 moves_todo |= move1022 moves_todo |= move._create_extra_move()1023 # Split moves where necessary and move quants1024 for move in moves_todo:1025 # To know whether we need to create a backorder or not, round to the general product's1026 # decimal precision and not the product's UOM.1027 rounding = self.env['decimal.precision'].precision_get('Product Unit of Measure')1028 if float_compare(move.quantity_done, move.product_uom_qty, precision_digits=rounding) < 0:1029 # Need to do some kind of conversion here1030 qty_split = move.product_uom._compute_quantity(move.product_uom_qty - move.quantity_done, move.product_id.uom_id, rounding_method='HALF-UP')1031 new_move = move._split(qty_split)1032 for move_line in move.move_line_ids:1033 if move_line.product_qty and move_line.qty_done:1034 # FIXME: there will be an issue if the move was partially available1035 # By decreasing `product_qty`, we free the reservation.1036 # FIXME: if qty_done > product_qty, this could raise if nothing is in stock...

Full Screen

Full Screen

ChessEngine.py

Source:ChessEngine.py Github

copy

Full Screen

...200 if moves[i].isEnpassantMove:201 capturedcol = moves[i].endCol202 capturedrow = moves[i].endRow+1 if self.whitetoMove else moves[i].endRow-1203 if not (capturedrow,capturedcol) in validSquares:204 moves.remove(moves[i])205 else:206 moves.remove(moves[i]) 207 else: #double check208 self.getKingMoves(kingRow,kingCol,moves)209 else: #not in check, so all moves are fine210 moves = self.getAllPossibleMoves()211212 if len(moves) == 0:213 if self.inCheck:214 self.checkMate = True215 else:216 self.staleMate = True217 else:218 self.checkMate = False219 self.staleMate = False220 221 return moves # Not gonna worry about chccks/pins right now222 223 224 '''225 All Moves without considering checks226 '''227 def getAllPossibleMoves(self):228 moves = []229 for r in range(len(self.board)): # Number of rows230 for c in range(len(self.board[r])): # Number of columns in giving row231 turn = self.board[r][c][0]232 if (turn == 'w' and self.whitetoMove) or (turn == 'b' and not self.whitetoMove):233 piece = self.board[r][c][1]234 self.moveFunctions[piece](r,c,moves) # call the appropriate move function based on the piece type235 return moves236237 '''238 Get all the pawn moves for the pawn located at row, col and add moves to list239 '''240 def getPawnMoves(self, r, c, moves):241 piecePinned = False242 pinDirection = ()243 for i in range(len(self.pins)-1,-1,-1):244 if self.pins[i][0] == r and self.pins[i][1] == c:245 piecePinned = True246 pinDirection = (self.pins[i][2],self.pins[i][3])247 self.pins.remove(self.pins[i])248 break249250 if self.whitetoMove:251 moveAmount = -1252 startRow = 6253 enemyColor = 'b'254 kingRow,kingCol = self.whiteKingLocation255 else:256 moveAmount= 1257 startRow = 1258 enemyColor = 'w'259 kingRow,kingCol = self.blackKingLocation260261 if self.board[r+moveAmount][c] == "--": # 1 square move262 if not piecePinned or pinDirection == (moveAmount,0):263 moves.append(Move((r,c),(r+moveAmount,c),self.board))264 if r==startRow and self.board[r+2*moveAmount][c] == "--":265 moves.append(Move((r,c),(r+2*moveAmount,c),self.board))266 # captures267 if c-1 >=0 : # capture to the left268 if not piecePinned or pinDirection == (moveAmount,-1):269 if self.board[r+moveAmount][c-1][0] == enemyColor:270 moves.append(Move((r,c),(r+moveAmount,c-1),self.board))271 if (r+moveAmount,c-1) == self.enpassantPossible:272 attackingPiece = blockingPiece = False273 if kingRow == r:274 if kingCol < c: #king is left of the pawn275 # inside btw king and pawn: outside range btw pawn order276 insideRange = range(kingCol+1,c-1)277 outsideRange = range(c+1,8)278 else: # king is right of the pawn279 insideRange = range(kingCol-1,c,-1)280 outsideRange = range(c-2,-1,-1)281282 for i in insideRange:283 if self.board[r][i] != "--": #some other piece, beside the en-passant pawn, blocks284 blockingPiece = True285 for i in outsideRange:286 square = self.board[r][i]287 if square[0] == enemyColor and (square[1]=='R' or square[1] == 'Q'):288 attackingPiece = True289 elif square != "--":290 blockingPiece = True291 292 if not attackingPiece or blockingPiece:293 moves.append(Move((r,c),(r+moveAmount,c-1),self.board,isEnpassantMove=True))294295 if c+1 <= 7:296 if not piecePinned or pinDirection == (moveAmount,1):297 if self.board[r+moveAmount][c+1][0] == enemyColor:298 moves.append(Move((r,c),(r+moveAmount,c+1),self.board))299 if (r+moveAmount,c+1) == self.enpassantPossible:300 attackingPiece = blockingPiece = False301 if kingRow == r:302 if kingCol < c: #king is left of the pawn303 # inside btw king and pawn: outside range btw pawn order304 insideRange = range(kingCol+1,c)305 outsideRange = range(c+2,8)306 else: # king is right of the pawn307 insideRange = range(kingCol-1,c+1,-1)308 outsideRange = range(c-1,-1,-1)309310 for i in insideRange:311 if self.board[r][i] != "--": #some other piece, beside the en-passant pawn, blocks312 blockingPiece = True313 for i in outsideRange:314 square = self.board[r][i]315 if square[0] == enemyColor and (square[1]=='R' or square[1] == 'Q'):316 attackingPiece = True317 elif square != "--":318 blockingPiece = True319 320 if not attackingPiece or blockingPiece:321 moves.append(Move((r,c),(r+moveAmount,c+1),self.board,isEnpassantMove=True))322 #add pawn promotion later323324325 # Get Rook Moves326 def getRookMoves(self, r, c, moves):327 piecePinned = False328 pinDirection = ()329 for i in range(len(self.pins)-1,-1,-1):330 if self.pins[i][0] == r and self.pins[i][1] == c:331 piecePinned = True332 pinDirection = (self.pins[i][2],self.pins[i][3])333 if self.board[r][c][1] != 'Q':334 self.pins.remove(self.pins[i])335 break336337 directions = ((-1,0),(0,-1),(1,0),(0,1)) #up,left,down,right338 enemyColor = "b" if self.whitetoMove else "w"339 for d in directions:340 for i in range(1,8):341 endRow = r + d[0]*i;342 endCol = c + d[1]*i;343 if 0 <= endRow < 8 and 0 <= endCol < 8: #on board344 if not piecePinned or pinDirection == d or pinDirection == (-d[0],-d[1]):345 endPiece = self.board[endRow][endCol]346 if endPiece == "--": # empty space, valid347 moves.append(Move((r,c),(endRow,endCol),self.board))348 elif endPiece[0] == enemyColor: # enemy piece349 moves.append(Move((r,c),(endRow,endCol),self.board))350 break351 else: # same color piece352 break353 else: #off board354 break355356 # Get Knight Moves357 def getKnightMoves(self, r, c, moves):358 piecePinned = False359 for i in range(len(self.pins)-1,-1,-1):360 if self.pins[i][0] == r and self.pins[i][1] == c:361 piecePinned = True362 self.pins.remove(self.pins[i])363 break364365 KnightMoves = ((-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1))366 allyColor = "w" if self.whitetoMove else "b"367 for m in KnightMoves:368 endRow = r + m[0]369 endCol = c + m[1]370 if 0 <= endRow < 8 and 0 <=endCol < 8:371 if not piecePinned:372 endPiece = self.board[endRow][endCol]373 if endPiece[0] != allyColor:374 moves.append(Move((r,c),(endRow,endCol),self.board))375 376377 def getBishopMoves(self, r, c, moves):378 piecePinned = False379 pinDirection = ()380 for i in range(len(self.pins)-1,-1,-1):381 if self.pins[i][0] == r and self.pins[i][1] == c:382 piecePinned = True383 pinDirection = (self.pins[i][2],self.pins[i][3])384 self.pins.remove(self.pins[i])385 break386387 directions = ((-1,-1),(-1,1),(1,-1),(1,1))388 enemyColor = "b" if self.whitetoMove else "w"389 for d in directions:390 for i in range(1,8):391 endRow = r + d[0]*i;392 endCol = c + d[1]*i;393 if 0 <= endRow < 8 and 0 <= endCol < 8: #on board394 if not piecePinned or pinDirection == d or pinDirection == (-d[0],-d[1]):395 endPiece = self.board[endRow][endCol]396 if endPiece == "--": # empty space, valid397 moves.append(Move((r,c),(endRow,endCol),self.board))398 elif endPiece[0] == enemyColor: # enemy piece ...

Full Screen

Full Screen

stock_traceability.py

Source:stock_traceability.py Github

copy

Full Screen

...147 def _quantity_to_str(self, from_uom, to_uom, qty):148 """ workaround to apply the float rounding logic of t-esc on data prepared server side """149 qty = from_uom._compute_quantity(qty, to_uom, rounding_method='HALF-UP')150 return self.env['ir.qweb.field.float'].value_to_html(qty, {'decimal_precision': 'Product Unit of Measure'})151 def make_dict_move(self, level, parent_id, move_line, stream=False, unfoldable=False):152 res_model, res_id, ref = self.get_links(move_line)153 data = [{154 'level': level,155 'unfoldable': unfoldable,156 'date': move_line.move_id.date,157 'parent_id': parent_id,158 'model_id': move_line.id,159 'model':'stock.move.line',160 'product_id': move_line.product_id.display_name,161 'product_qty_uom': "%s %s" % (self._quantity_to_str(move_line.product_uom_id, move_line.product_id.uom_id, move_line.qty_done), move_line.product_id.uom_id.name),162 'location': move_line.location_id.name + ' -> ' + move_line.location_dest_id.name,163 'reference_id': ref,164 'res_id': res_id,165 'stream': stream,166 'res_model': res_model}]167 return data168 def make_dict_head(self, level, parent_id, model=False, stream=False, move_line=False):169 data = []170 if model == 'stock.move.line':171 data = [{172 'level': level,173 'unfoldable': True,174 'date': move_line.move_id.date,175 'model_id': move_line.id,176 'parent_id': parent_id,177 'model': model or 'stock.move.line',178 'product_id': move_line.product_id.display_name,179 'lot_id': move_line.lot_id.name,180 'product_qty_uom': "%s %s" % (self._quantity_to_str(move_line.product_uom_id, move_line.product_id.uom_id, move_line.qty_done), move_line.product_id.uom_id.name),181 'location': move_line.location_dest_id.name,182 'stream': stream,183 'reference_id': False}]184 elif model == 'stock.quant':185 data = [{186 'level': level,187 'unfoldable': True,188 'date': move_line.write_date,189 'model_id': move_line.id,190 'parent_id': parent_id,191 'model': model or 'stock.quant',192 'product_id': move_line.product_id.display_name,193 'lot_id': move_line.lot_id.name,194 'product_qty_uom': "%s %s" % (self._quantity_to_str(move_line.product_uom_id, move_line.product_id.uom_id, move_line.quantity), move_line.product_id.uom_id.name),195 'location': move_line.location_id.name,196 'stream': stream,197 'reference_id': False}]198 return data199 @api.model200 def upstream_traceability(self, level, stream=False, line_id=False, model=False, model_obj=False, parent_quant=False):201 final_vals =[]202 if model == 'stock.move.line':203 moves = self.get_move_lines_upstream(model_obj)204 elif model == 'stock.quant':205 moves = self.env['stock.move.line'].search([206 ('location_dest_id', '=', model_obj.location_id.id),207 ('lot_id', '=', model_obj.lot_id.id),208 ('date', '<=', model_obj.write_date),209 ('state', '=', 'done'),210 ])211 moves |= self.get_move_lines_upstream(moves)212 for move in moves:213 unfoldable = False214 if move.consume_line_ids:215 unfoldable = True216 final_vals += self.make_dict_move(level, stream=stream, parent_id=line_id, move_line=move, unfoldable=unfoldable)217 return final_vals218 @api.model219 def downstream_traceability(self, level, stream=False, line_id=False, model=False, model_obj=False, parent_quant=False):220 final_vals = []221 if model == 'stock.move.line':222 moves = self.get_move_lines_downstream(model_obj)223 elif model == 'stock.quant':224 moves = self.env['stock.move.line'].search([225 ('location_id', '=', model_obj.location_id.id),226 ('lot_id', '=', model_obj.lot_id.id),227 ('date', '>=', model_obj.write_date),228 ('state', '=', 'done'),229 ])230 moves |= self.get_move_lines_downstream(moves)231 for move in moves:232 unfoldable = False233 if move.produce_line_ids:234 unfoldable = True235 final_vals += self.make_dict_move(level, stream=stream, parent_id=line_id, move_line=move, unfoldable=unfoldable)236 return final_vals237 @api.model238 def final_vals_to_lines(self, final_vals, level):239 lines = []240 for data in final_vals:241 lines.append({242 'id': autoIncrement(),243 'model': data['model'],244 'model_id': data['model_id'],245 'stream': data['stream'] or 'upstream',246 'parent_id': data['parent_id'],247 'parent_quant': data.get('parent_quant', False),248 'type': 'line',249 'reference': data.get('reference_id', False),250 'res_id': data.get('res_id', False),251 'res_model': data.get('res_model', False),252 'name': _(data.get('lot_id', False)),253 'columns': [data.get('reference_id', False) or data.get('product_id', False),254 data.get('lot_id', False),255 data.get('date', False),256 data.get('product_qty_uom', 0),257 data.get('location', False)],258 'level': level,259 'unfoldable': data['unfoldable'],260 })261 return lines262 @api.model263 def _lines(self, line_id=None, model_id=False, model=False, level=0, parent_quant=False, stream=False, obj_ids=[], **kw):264 final_vals = []265 if model and line_id:266 model_obj = self.env[model].browse(model_id)267 if stream == "downstream":268 final_vals += self.downstream_traceability(level, stream='downstream', line_id=line_id, model=model, model_obj=model_obj, parent_quant=parent_quant)269 if model == 'stock.move.line':270 if model_obj.produce_line_ids:271 final_vals += self.get_produced_or_consumed_vals(model_obj.produce_line_ids, level, model=model, stream=stream, parent_id=line_id)272 else:273 final_vals = self.make_dict_move(level, stream=stream, parent_id=line_id,move_line=model_obj) + final_vals274 else:275 final_vals += self.upstream_traceability(level, stream='upstream', line_id=line_id, model=model, model_obj=model_obj, parent_quant=parent_quant)276 if model == 'stock.move.line':277 if model_obj.consume_line_ids:278 final_vals += self.get_produced_or_consumed_vals(model_obj.consume_line_ids, level, model=model, stream=stream, parent_id=line_id)279 else:280 final_vals = self.make_dict_move(level, stream=stream, parent_id=line_id, move_line=model_obj) + final_vals281 else:282 for move_line in obj_ids:283 final_vals += self.make_dict_head(level, stream=stream, parent_id=line_id, model=model or 'stock.pack.operation', move_line=move_line)284 return final_vals285 @api.model286 def get_produced_or_consumed_vals(self, move_lines, level, model, stream, parent_id):287 final_vals = []288 for line in move_lines:289 final_vals += self.make_dict_head(level, model=model, stream=stream, parent_id=parent_id, move_line=line)290 return final_vals291 def get_pdf_lines(self, line_data=[]):292 final_vals = []293 lines = []294 for line in line_data:295 model = self.env[line['model_name']].browse(line['model_id'])296 if line.get('unfoldable'):297 final_vals += self.make_dict_head(line['level'], model=line['model_name'], parent_id=line['id'], move_line=model)298 else:299 if line['model_name'] == 'stock.move.line':300 final_vals += self.make_dict_move(line['level'], parent_id=line['id'], move_line=model)301 for data in final_vals:302 lines.append({303 'id': autoIncrement(),304 'model': data['model'],305 'model_id': data['model_id'],306 'parent_id': data['parent_id'],307 'stream': "%s" % (data['stream']),308 'type': 'line',309 'name': _(data.get('lot_id')),310 'columns': [data.get('reference_id') or data.get('product_id'),311 data.get('lot_id'),312 data.get('date'),313 data.get('product_qty_uom', 0),314 data.get('location')],...

Full Screen

Full Screen

mrp_product_produce.py

Source:mrp_product_produce.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2# Part of Odoo. See LICENSE file for full copyright and licensing details.3from collections import Counter4from datetime import datetime5from odoo import api, fields, models, _6from odoo.addons import decimal_precision as dp7from odoo.exceptions import UserError, ValidationError8from odoo.tools import float_compare, float_round9class MrpProductProduce(models.TransientModel):10 _name = "mrp.product.produce"11 _description = "Record Production"12 @api.model13 def default_get(self, fields):14 res = super(MrpProductProduce, self).default_get(fields)15 if self._context and self._context.get('active_id'):16 production = self.env['mrp.production'].browse(self._context['active_id'])17 serial_finished = (production.product_id.tracking == 'serial')18 if serial_finished:19 todo_quantity = 1.020 else:21 main_product_moves = production.move_finished_ids.filtered(lambda x: x.product_id.id == production.product_id.id)22 todo_quantity = production.product_qty - sum(main_product_moves.mapped('quantity_done'))23 todo_quantity = todo_quantity if (todo_quantity > 0) else 024 if 'production_id' in fields:25 res['production_id'] = production.id26 if 'product_id' in fields:27 res['product_id'] = production.product_id.id28 if 'product_uom_id' in fields:29 res['product_uom_id'] = production.product_uom_id.id30 if 'serial' in fields:31 res['serial'] = bool(serial_finished)32 if 'product_qty' in fields:33 res['product_qty'] = todo_quantity34 if 'produce_line_ids' in fields:35 lines = []36 for move in production.move_raw_ids.filtered(lambda x: (x.product_id.tracking != 'none') and x.state not in ('done', 'cancel') and x.bom_line_id):37 qty_to_consume = float_round(todo_quantity / move.bom_line_id.bom_id.product_qty * move.bom_line_id.product_qty,38 precision_rounding=move.product_uom.rounding, rounding_method="UP")39 for move_line in move.move_line_ids:40 if float_compare(qty_to_consume, 0.0, precision_rounding=move.product_uom.rounding) <= 0:41 break42 if move_line.lot_produced_id or float_compare(move_line.product_uom_qty, move_line.qty_done, precision_rounding=move.product_uom.rounding) <= 0:43 continue44 to_consume_in_line = min(qty_to_consume, move_line.product_uom_qty)45 lines.append({46 'move_id': move.id,47 'qty_to_consume': to_consume_in_line,48 'qty_done': 0.0,49 'lot_id': move_line.lot_id.id,50 'product_uom_id': move.product_uom.id,51 'product_id': move.product_id.id,52 })53 qty_to_consume -= to_consume_in_line54 if float_compare(qty_to_consume, 0.0, precision_rounding=move.product_uom.rounding) > 0:55 if move.product_id.tracking == 'serial':56 while float_compare(qty_to_consume, 0.0, precision_rounding=move.product_uom.rounding) > 0:57 lines.append({58 'move_id': move.id,59 'qty_to_consume': 1,60 'qty_done': 0.0,61 'product_uom_id': move.product_uom.id,62 'product_id': move.product_id.id,63 })64 qty_to_consume -= 165 else:66 lines.append({67 'move_id': move.id,68 'qty_to_consume': qty_to_consume,69 'qty_done': 0.0,70 'product_uom_id': move.product_uom.id,71 'product_id': move.product_id.id,72 })73 res['produce_line_ids'] = [(0, 0, x) for x in lines]74 return res75 serial = fields.Boolean('Requires Serial')76 production_id = fields.Many2one('mrp.production', 'Production')77 product_id = fields.Many2one('product.product', 'Product')78 product_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True)79 product_uom_id = fields.Many2one('product.uom', 'Unit of Measure')80 lot_id = fields.Many2one('stock.production.lot', string='Lot')81 produce_line_ids = fields.One2many('mrp.product.produce.line', 'product_produce_id', string='Product to Track')82 product_tracking = fields.Selection(related="product_id.tracking")83 @api.multi84 def do_produce(self):85 # Nothing to do for lots since values are created using default data (stock.move.lots)86 quantity = self.product_qty87 if float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) <= 0:88 raise UserError(_("The production order for '%s' has no quantity specified") % self.product_id.display_name)89 for move in self.production_id.move_raw_ids:90 # TODO currently not possible to guess if the user updated quantity by hand or automatically by the produce wizard.91 if move.product_id.tracking == 'none' and move.state not in ('done', 'cancel') and move.unit_factor:92 rounding = move.product_uom.rounding93 if self.product_id.tracking != 'none':94 qty_to_add = float_round(quantity * move.unit_factor, precision_rounding=rounding)95 move._generate_consumed_move_line(qty_to_add, self.lot_id)96 elif len(move._get_move_lines()) < 2:97 move.quantity_done += float_round(quantity * move.unit_factor, precision_rounding=rounding)98 else:99 move._set_quantity_done(quantity * move.unit_factor)100 for move in self.production_id.move_finished_ids:101 if move.product_id.tracking == 'none' and move.state not in ('done', 'cancel'):102 rounding = move.product_uom.rounding103 if move.product_id.id == self.production_id.product_id.id:104 move.quantity_done += float_round(quantity, precision_rounding=rounding)105 elif move.unit_factor:106 # byproducts handling107 move.quantity_done += float_round(quantity * move.unit_factor, precision_rounding=rounding)108 self.check_finished_move_lots()109 if self.production_id.state == 'confirmed':110 self.production_id.write({111 'state': 'progress',112 'date_start': datetime.now(),113 })114 return {'type': 'ir.actions.act_window_close'}115 @api.multi116 def check_finished_move_lots(self):117 produce_move = self.production_id.move_finished_ids.filtered(lambda x: x.product_id == self.product_id and x.state not in ('done', 'cancel'))118 if produce_move and produce_move.product_id.tracking != 'none':119 if not self.lot_id:120 raise UserError(_('You need to provide a lot for the finished product'))121 existing_move_line = produce_move.move_line_ids.filtered(lambda x: x.lot_id == self.lot_id)122 if existing_move_line:123 if self.product_id.tracking == 'serial':124 raise UserError(_('You cannot produce the same serial number twice.'))125 existing_move_line.product_uom_qty += self.product_qty126 existing_move_line.qty_done += self.product_qty127 else:128 vals = {129 'move_id': produce_move.id,130 'product_id': produce_move.product_id.id,131 'production_id': self.production_id.id,132 'product_uom_qty': self.product_qty,133 'product_uom_id': produce_move.product_uom.id,134 'qty_done': self.product_qty,135 'lot_id': self.lot_id.id,136 'location_id': produce_move.location_id.id,137 'location_dest_id': produce_move.location_dest_id.id,138 }139 self.env['stock.move.line'].create(vals)140 for pl in self.produce_line_ids:141 if pl.qty_done:142 if not pl.lot_id:143 raise UserError(_('Please enter a lot or serial number for %s !' % pl.product_id.name))144 if not pl.move_id:145 # Find move_id that would match146 move_id = self.production_id.move_raw_ids.filtered(lambda x: x.product_id == pl.product_id and x.state not in ('done', 'cancel'))147 if move_id:148 pl.move_id = move_id149 else:150 # create a move and put it in there151 order = self.production_id152 pl.move_id = self.env['stock.move'].create({153 'name': order.name,154 'product_id': pl.product_id.id,155 'product_uom': pl.product_uom_id.id,156 'location_id': order.location_src_id.id,157 'location_dest_id': self.product_id.property_stock_production.id,158 'raw_material_production_id': order.id,159 'group_id': order.procurement_group_id.id,160 'origin': order.name,161 'state': 'confirmed'})162 pl.move_id._generate_consumed_move_line(pl.qty_done, self.lot_id, lot=pl.lot_id)163 return True164class MrpProductProduceLine(models.TransientModel):165 _name = "mrp.product.produce.line"166 _description = "Record Production Line"167 product_produce_id = fields.Many2one('mrp.product.produce')168 product_id = fields.Many2one('product.product', 'Product')169 lot_id = fields.Many2one('stock.production.lot', 'Lot')170 qty_to_consume = fields.Float('To Consume', digits=dp.get_precision('Product Unit of Measure'))171 product_uom_id = fields.Many2one('product.uom', 'Unit of Measure')172 qty_done = fields.Float('Done', digits=dp.get_precision('Product Unit of Measure'))173 move_id = fields.Many2one('stock.move')174 @api.onchange('lot_id')175 def _onchange_lot_id(self):176 """ When the user is encoding a produce line for a tracked product, we apply some logic to177 help him. This onchange will automatically switch `qty_done` to 1.0.178 """179 res = {}180 if self.product_id.tracking == 'serial':181 self.qty_done = 1182 return res183 @api.onchange('qty_done')184 def _onchange_qty_done(self):185 """ When the user is encoding a produce line for a tracked product, we apply some logic to186 help him. This onchange will warn him if he set `qty_done` to a non-supported value.187 """188 res = {}189 if self.product_id.tracking == 'serial':190 if float_compare(self.qty_done, 1.0, precision_rounding=self.move_id.product_id.uom_id.rounding) != 0:191 message = _('You can only process 1.0 %s for products with unique serial number.') % self.product_id.uom_id.name192 res['warning'] = {'title': _('Warning'), 'message': message}193 return res194 @api.onchange('product_id')195 def _onchange_product_id(self):...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fMBT automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful