From 9c4f131ffaf37ca47a78b320a68f7de4e846ecfb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 19 Nov 2025 14:44:57 +0700 Subject: push --- indoteknik_api/controllers/api_v1/stock_picking.py | 119 +++++++++++++-------- 1 file changed, 77 insertions(+), 42 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 92bc91bb..ddbb89ad 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -260,23 +260,17 @@ class StockPicking(controller.Controller): def get_picking_by_name(self, **kw): name = str(kw.get('name')) if not name: - return Response( - json.dumps({'status': 'error', 'message': 'Field name is required'}), - content_type='application/json', - status=400 - ) + 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[0].picking_id + picking = move_dest.move_dest_ids.filtered(lambda m: m.state not in ['done', 'cancel']).picking_id if not picking: - return Response( - json.dumps({'status': 'error', 'message': f'Picking {name} not found'}), - content_type='application/json', - status=404 - ) + return self.response({'status': 'error', 'message': 'Picking not found'}) lines = [] for move in picking.move_line_ids_without_package: @@ -306,53 +300,94 @@ class StockPicking(controller.Controller): return self.response(data) - @http.route('/api/v1/locator/picking/update', auth='public', methods=['POST'], csrf=False) + @http.route('/api/v1/locator/picking/update', auth='public', methods=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() - def update_picking_lines(self, **payload): - picking_id = payload.get('picking_id') - updates = payload.get('lines', []) + 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 {'status': 'error', 'message': 'Picking not found'} + return self.response({'status': 'error', 'message': 'Picking not found'}) for line in updates: - move = request.env['stock.move'].sudo().browse(line['move_id']) + move = request.env['stock.move.line'].sudo().browse(line['move_id']) if not move.exists(): continue - for move_line in move.move_line_ids: + 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 'location_id' in line: - move_line.location_id = line['location_id'] - if 'location_dest_id' in line: - move_line.location_dest_id = line['location_dest_id'] + 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 {'status': 'success', 'message': 'Picking updated'} + return self.response({'status': 'success', 'message': 'Picking updated'}) - @http.route('/api/v1/locator/picking/validate', auth='public', methods=['POST'], csrf=False) + @http.route('/api/v1/locator/picking/validate', auth='public', methods=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() - def validate_picking(self, **payload): - picking_id = payload.get('picking_id') - picking = request.env['stock.picking'].sudo().browse(picking_id) - if not picking.exists(): - return {'status': 'error', 'message': 'Picking not found'} - + def validate_picking(self, **kw): try: - backorder = picking._create_backorder() - except Exception: + 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 - picking.button_validate() + if isinstance(action, dict) and action.get('res_model') == 'stock.backorder.confirmation': - result = { - 'status': 'success', - 'picking_name': picking.name, - 'validated': True, - 'backorder_created': bool(backorder), - } + 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) + }) - if backorder: - result['backorder_name'] = backorder.name - return result + 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 -- cgit v1.2.3