diff options
Diffstat (limited to 'indoteknik_api/controllers/api_v1')
| -rw-r--r-- | indoteknik_api/controllers/api_v1/stock_picking.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index c19812f5..94d0035f 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -307,3 +307,140 @@ class StockPicking(controller.Controller): } ) + + @http.route(prefix + 'locator/picking', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_picking_by_name(self, **kw): + name = str(kw.get('name')) + if not name: + return self.response({'status': 'error', 'message': 'Picking name is required'}) + + picking = request.env['stock.picking'].search([('name', 'ilike', name)], limit=1) + if 'BU/INPUT/' in name: + if picking.state != 'done': + return self.response({'status': 'error', 'message': 'BU Input nya belum done'}) + move_dest = picking.move_ids_without_package[0] + picking = move_dest.move_dest_ids.filtered(lambda m: m.state not in ['done', 'cancel']).picking_id + + if not picking: + return self.response({'status': 'error', 'message': 'Picking not found'}) + + lines = [] + for move in picking.move_line_ids_without_package: + lines.append({ + 'move_id': move.id, + 'product_id': move.product_id.id, + 'product_name': move.product_id.display_name, + 'product_uom_qty': move.product_uom_qty, + 'qty_done': move.qty_done, + 'uom_name': move.product_uom_id.name, + 'source_location': move.location_id.complete_name, + 'dest_location': move.location_dest_id.complete_name, + }) + + data = { + 'status': 'success', + 'picking': { + 'id': picking.id, + 'name': picking.name, + 'type_code': picking.picking_type_id.code, + 'source_location': picking.location_id.complete_name, + 'dest_location': picking.location_dest_id.complete_name, + 'state': picking.state, + 'lines': lines, + } + } + + return self.response(data) + + @http.route('/api/v1/locator/picking/update', auth='public', methods=['POST', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def update_picking_lines(self, **kw): + picking_id = int(kw.get('picking_id')) + lines_str = kw.get('lines', '[]') + try: + updates = json.loads(lines_str) + except: + updates = [] + + picking = request.env['stock.picking'].sudo().browse(picking_id) + if not picking.exists(): + return self.response({'status': 'error', 'message': 'Picking not found'}) + + for line in updates: + move = request.env['stock.move.line'].sudo().browse(line['move_id']) + if not move.exists(): + continue + + location_id, location_dest_id = self.get_location_locator(line) + + for move_line in move: + move_line.qty_done = line.get('qty_done', move_line.qty_done) + if 'source_location' in line: + move_line.location_id = location_id + if 'dest_location' in line: + move_line.location_dest_id = location_dest_id + + return self.response({'status': 'success', 'message': 'Picking updated'}) + + @http.route('/api/v1/locator/picking/validate', auth='public', methods=['POST', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def validate_picking(self, **kw): + try: + picking_id = int(kw.get('picking_id')) + picking = request.env['stock.picking'].sudo().browse(picking_id) + + if not picking.exists(): + return self.response({ + 'status': 'error', + 'message': 'Picking not found' + }) + + action = picking.button_validate() + backorder = None + + if isinstance(action, dict) and action.get('res_model') == 'stock.backorder.confirmation': + + ctx = action.get('context', {}) or {} + + pick_ids = ctx.get('default_pick_ids') or [] + + if pick_ids and isinstance(pick_ids[0], (tuple, list)): + pick_ids = [p[1] for p in pick_ids] + + Wizard = request.env['stock.backorder.confirmation'].with_context({ + **ctx, + "default_pick_ids": pick_ids, + "button_validate_picking_ids": pick_ids, + }).sudo() + + wizard = Wizard.create({}) + + # --- Step 4: Jalankan wizard.process() → Odoo create backorder --- + wizard.process() + + # --- Step 5: Ambil backorder --- + backorder = request.env['stock.picking'].sudo().search([ + ('backorder_id', '=', picking.id) + ], limit=1) + + # --- FINAL RESPONSE --- + return self.response({ + 'status': 'success', + 'picking_name': picking.name, + 'validated': True, + 'backorder_created': bool(backorder), + 'backorder_name': backorder.name if backorder else None, + }) + + except Exception as e: + return self.response({ + 'status': 'error', + 'message': str(e) + }) + + + def get_location_locator(self, line): + location_id = request.env['stock.location'].sudo().search([('complete_name', '=', line.get('source_location'))], limit=1).id + location_dest_id = request.env['stock.location'].sudo().search([('complete_name', '=', line.get('dest_location'))], limit=1).id + return location_id, location_dest_id
\ No newline at end of file |
