diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-09-29 13:20:20 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-09-29 13:20:20 +0700 |
| commit | 875b20796c7fa64abebe430b2707df597e29836b (patch) | |
| tree | 2521fbf09f4695253fd7db1ff7613b7f003f20ea /indoteknik_api/controllers/api_v1 | |
| parent | 914bcd75dd2baddb2841cbfba6a64ebd453fecdb (diff) | |
| parent | ec21c4721f35028fc9b2a61bd0dbc6e4bf600e74 (diff) | |
Merge branch 'odoo-backup' into pum-v2
# Conflicts:
# indoteknik_custom/security/ir.model.access.csv
Diffstat (limited to 'indoteknik_api/controllers/api_v1')
| -rw-r--r-- | indoteknik_api/controllers/api_v1/partner.py | 11 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 217 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/stock_picking.py | 58 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/user.py | 4 |
4 files changed, 198 insertions, 92 deletions
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py index b1d8d5f3..8d67800c 100644 --- a/indoteknik_api/controllers/api_v1/partner.py +++ b/indoteknik_api/controllers/api_v1/partner.py @@ -295,7 +295,14 @@ class Partner(controller.Controller): partner = partner.parent_id or partner - if any(line.days == 0 for line in partner.property_payment_term_id.line_ids): + payment_term = ( + partner.previous_payment_term_id + if partner.is_cbd_locked + else partner.property_payment_term_id + ) + + # if any(line.days == 0 for line in partner.property_payment_term_id.line_ids): + if any(line.days == 0 for line in payment_term.line_ids): return self.response(code=402, description='Partner not tempo') domain_result_tempo = [('partner_id', '=', partner.id), ('payment_state', '=', 'not_paid'), ('state', '=', 'posted')] @@ -315,7 +322,7 @@ class Partner(controller.Controller): data = { 'name': partner.name, - 'payment_term': partner.property_payment_term_id.name, + 'payment_term': payment_term.name, 'amount_due': result_tempo, 'amount_due_total': result_tempo_total, 'amount_jatuh_tempo_total': result_jatuh_tempo_total, diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 374b49a2..1a75c830 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -22,7 +22,7 @@ class SaleOrder(controller.Controller): }) sale_order_line = request.env['sale.order.line'].search([ - ('product_id', '=', product_id), + ('product_id', '=', product_id), ('order_id', '=', so_id) ], limit=1) @@ -41,7 +41,7 @@ class SaleOrder(controller.Controller): return self.response('work') else: return self.response('Sale order line not found', status=404) - + @http.route(prefix + "sale_order_number", auth='public', method=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_number_sale_order(self, **kw): @@ -87,8 +87,8 @@ class SaleOrder(controller.Controller): 'amount_tax': sale.amount_tax, 'amount_total': sale.amount_total, 'expected_ready_to_ship': f"{sale.expected_ready_to_ship.day} {INDONESIAN_MONTHS[sale.expected_ready_to_ship.month]} {sale.expected_ready_to_ship.year}", - 'eta_date_start': f"{sale.eta_date_start.day} {INDONESIAN_MONTHS[sale.eta_date_start.month]} {sale.eta_date_start.year}", - 'eta_date_end': f"{sale.eta_date.day} {INDONESIAN_MONTHS[sale.eta_date.month]} {sale.eta_date.year}", + # 'eta_date_start': f"{sale.eta_date_start.day} {INDONESIAN_MONTHS[sale.eta_date_start.month]} {sale.eta_date_start.year}", + # 'eta_date_end': f"{sale.eta_date.day} {INDONESIAN_MONTHS[sale.eta_date.month]} {sale.eta_date.year}", 'product_name': product_name, 'product_not_in_id': product_not_in_id, 'details': [request.env['sale.order.line'].api_single_response(x, context='with_detail') for x in sale.order_line] @@ -116,14 +116,12 @@ class SaleOrder(controller.Controller): if not params['valid']: return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids( - params['value']['partner_id']) + partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) domain = [('partner_id', 'in', partner_child_ids)] context = params['value']['context'] if context == 'quotation': - domain += ["|", "|", ("state", "=", "draft"), - ("state", "=", "sent"), ("state", "=", "cancel")] + domain += ["|", "|", ("state", "=", "draft"), ("state", "=", "sent"), ("state", "=", "cancel")] if not context: domain += ["|", ("state", "=", "sale"), ("state", "=", "done")] @@ -135,39 +133,39 @@ class SaleOrder(controller.Controller): ('product_id.name', 'ilike', name), ('product_id.default_code', 'ilike', name), ]) - sale_order_ids_from_lines = order_lines.mapped('order_id.id') - domain += ['|', '|', - ('name', 'ilike', name), - ('partner_purchase_order_name', 'ilike', name), - ('id', 'in', sale_order_ids_from_lines) - ] - + ('name', 'ilike', name), + ('partner_purchase_order_name', 'ilike', name), + ('id', 'in', sale_order_ids_from_lines) + ] + if params['value']['site']: site = params['value']['site'].replace(' ', '%') - domain += [ - ('partner_id.site_id.name', 'ilike', '%' + site + '%') - ] + domain += [('partner_id.site_id.name', 'ilike', '%' + site + '%')] status = params['value'].get('status') if status: if status == 'quotation': domain += [('state', '=', 'draft')] domain += [('approval_status', '=', False)] - elif status == 'cancel': domain += [('state', '=', 'cancel')] - + elif status == 'belum_bayar': + domain += [ + ('state', '=', 'draft'), + ('approval_status', 'in', ['pengajuan1', 'pengajuan2']), + ('payment_status', 'in', [False, None, '', 'pending', 'expire']) + ] elif status == 'diproses': domain += [ ('state', '=', 'draft'), ('approval_status', 'in', ['pengajuan1', 'pengajuan2']), + ('payment_status', '!=', False), + ('payment_status', 'not in', ['', 'pending', 'expire']), ] - elif status in ['dikemas', 'dikirim', 'selesai', 'partial']: domain += [('state', '=', 'sale')] - elif status == 'all': domain += [] @@ -179,7 +177,7 @@ class SaleOrder(controller.Controller): elif params['value']['sort'] == 'desc': order = 'amount_total desc' - # Filter berdasarkan tanggal order + # Filter tanggal try: if params['value']['startDate'] and params['value']['endDate']: start_date = datetime.strptime(params['value']['startDate'], '%d/%m/%Y').strftime('%Y-%m-%d 00:00:00') @@ -190,22 +188,17 @@ class SaleOrder(controller.Controller): domain.append(('date_order', '>=', start_date)) domain.append(('date_order', '<=', end_date)) - except ValueError: return self.response(code=400, description="Invalid date format. Use 'DD/MM/YYYY'.") + sale_orders = request.env['sale.order'].search(domain, order=order) - - sale_orders = request.env['sale.order'].search( - domain, order=order) + # Filter status pengiriman status = params['value'].get('status') if status in ['dikemas', 'dikirim', 'selesai', 'partial']: filtered_orders = [] for sale_order in sale_orders: - bu_pickings = [ - p for p in sale_order.picking_ids - if p.picking_type_id and p.picking_type_id.id == 29 - ] + bu_pickings = [p for p in sale_order.picking_ids if p.picking_type_id and p.picking_type_id.id == 29 and p.state != 'cancel'] total = len(bu_pickings) done_pickings = [p for p in bu_pickings if p.state == 'done'] done_with_driver = [p for p in done_pickings if p.sj_return_date] @@ -213,25 +206,56 @@ class SaleOrder(controller.Controller): if status == 'dikemas' and len(done_pickings) == 0: filtered_orders.append(sale_order) - elif status == 'dikirim' and len(done_pickings) == total and len(done_pickings) > 0 and len(done_without_driver) == total: + elif status == 'dikirim' and len(done_pickings) == total and len(done_pickings) > 0 and len( + done_without_driver) == total: filtered_orders.append(sale_order) - elif status == 'selesai' and len(done_pickings) == total and len(done_pickings) > 0 and len(done_with_driver) == total: + elif status == 'selesai' and len(done_pickings) == total and len(done_pickings) > 0 and len( + done_with_driver) == total: filtered_orders.append(sale_order) elif status == 'partial' and ( - len(done_pickings) != total or - (done_with_driver and done_without_driver) - ): + len(done_pickings) != total or (done_with_driver and done_without_driver)): filtered_orders.append(sale_order) else: filtered_orders = sale_orders filtered_orders_paginated = filtered_orders[offset: offset + limit] + # === Ringkasan (tanpa auto-generate) === + CBD_PAYMENT_TERM_ID = 26 + ALLOWED_CONTINUE = {'', 'pending', 'capture', 'expire', 'cancel'} # boleh munculkan "Bayar Sekarang" + + def _is_website_order(so): + return bool(so.source_id and so.source_id.id == 59) + + sale_orders_payload = [] + for so in filtered_orders_paginated: + item = request.env['sale.order'].api_v1_single_response(so) + + approval_ok = (so.approval_status in ('pengajuan1', 'pengajuan2')) + source_ok = _is_website_order(so) + term_ok = bool(so.payment_term_id and so.payment_term_id.id == CBD_PAYMENT_TERM_ID) + pay_status = (getattr(so, 'payment_status', '') or '').strip().lower() + eligible = bool(approval_ok and source_ok and term_ok and pay_status in ALLOWED_CONTINUE) + + redirect_url = getattr(so, 'payment_link_midtrans', '') or '' + + item.update({ + 'eligibleContinue': eligible, + 'paymentSummary': { + 'eligible': eligible, + 'approvalStatus': so.approval_status or '', + 'paymentStatus': pay_status, + 'paymentTermId': so.payment_term_id.id if so.payment_term_id else None, + 'sourceId': so.source_id.id if so.source_id else None, + 'redirectUrl': redirect_url, + } + }) + sale_orders_payload.append(item) + data = { 'sale_order_total': len(filtered_orders), - 'sale_orders': [request.env['sale.order'].api_v1_single_response(x) for x in filtered_orders_paginated] + 'sale_orders': sale_orders_payload } - return self.response(data) @http.route(PREFIX_PARTNER + 'sale_order/<id>', auth='public', method=['GET', 'OPTIONS']) @@ -240,6 +264,7 @@ class SaleOrder(controller.Controller): params = self.get_request_params(kw, { 'partner_id': ['number'], 'id': ['number'], + 'ensure_payment_link': [], # optional flag }) if not params['valid']: return self.response(code=400, description=params) @@ -247,9 +272,60 @@ class SaleOrder(controller.Controller): partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) domain = [('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids)] data = {} + sale_order = request.env['sale.order'].search(domain) if sale_order: data = request.env['sale.order'].api_v1_single_response(sale_order, context='with_detail') + + CBD_PAYMENT_TERM_ID = 26 + ALLOWED_CONTINUE = {'', 'pending', 'capture', 'expire', 'cancel'} + + def _is_website_order(so): + return bool(so.source_id and so.source_id.id == 59) + + pay_status = (getattr(sale_order, 'payment_status', '') or '').strip().lower() + eligible = ( + sale_order.approval_status in ('pengajuan1', 'pengajuan2') and + _is_website_order(sale_order) and + sale_order.payment_term_id and sale_order.payment_term_id.id == CBD_PAYMENT_TERM_ID and + pay_status in ALLOWED_CONTINUE + ) + + redirect_url = getattr(sale_order, 'payment_link_midtrans', '') or '' + + ensure_raw = params['value'].get('ensure_payment_link') + ensure_flag = False + if ensure_raw is not None: + s = str(ensure_raw).strip().lower() + ensure_flag = s not in ('', '0', 'false', 'no', 'none') + + if ensure_flag and eligible: + should_generate = False + if not redirect_url: + should_generate = True + elif pay_status in ('expire', 'cancel'): + should_generate = True + + if should_generate: + try: + sale_order.sudo().generate_payment_link_midtrans_sales_order() + redirect_url = getattr(sale_order, 'payment_link_midtrans', '') or '' + except Exception as e: + _logger.warning(f'Generate Midtrans gagal untuk SO {sale_order.id}: {e}') + + data.update({ + 'eligible_continue': eligible, + 'payment_summary': { + 'eligible': eligible, + 'approval_status': sale_order.approval_status or '', + 'payment_status': pay_status, + 'payment_term_id': sale_order.payment_term_id.id if sale_order.payment_term_id else None, + 'source_id': sale_order.source_id.id if sale_order.source_id else None, + 'redirect_url': redirect_url, + } + }) + + # formatting tanggal (tetap sama) if sale_order.expected_ready_to_ship: bulan_id = [ "Januari", "Februari", "Maret", "April", "Mei", "Juni", @@ -259,6 +335,7 @@ class SaleOrder(controller.Controller): bulan = bulan_id[sale_order.expected_ready_to_ship.month - 1] tahun = sale_order.expected_ready_to_ship.year data['expected_ready_to_ship'] = f"{tanggal} {bulan} {tahun}" + if sale_order.eta_date_start: bulan_id = [ "Januari", "Februari", "Maret", "April", "Mei", "Juni", @@ -307,12 +384,12 @@ class SaleOrder(controller.Controller): sale_order.approval_status = 'pengajuan2' elif sale_order._requires_approval_margin_manager(): sale_order.approval_status = 'pengajuan1' - + data = request.env['sale.order'].api_v1_single_response( sale_order, context='with_detail') return self.response(data) - + @http.route(PREFIX_PARTNER + 'sale_order/<id>/approve', auth='public', method=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized(private=True, private_key='partner_id') def partner_approve_sale_order_by_id(self, **kw): @@ -320,27 +397,27 @@ class SaleOrder(controller.Controller): 'partner_id': ['number'], 'id': ['number'] }) - + if not params['valid']: return self.response(code=400, description=params) - + value = params['value'] partner_child_ids = self.get_partner_child_ids(value['partner_id']) - + sale_order = request.env['sale.order'].search([ ('id', '=', value['id']), ('partner_id', 'in', partner_child_ids) ]) if not sale_order: return self.response(code=404, description='Sale Order not found') - + partner = request.env['res.partner'].browse(value['partner_id']) if not partner.web_role: return self.response(code=400, description='Unauthorized') - + if partner.web_role: sale_order.web_approval = 'cust_%s' % partner.web_role - + if sale_order.web_approval in ['cust_procurement', 'cust_director']: if sale_order._requires_approval_margin_leader(): sale_order.approval_status = 'pengajuan2' @@ -348,7 +425,7 @@ class SaleOrder(controller.Controller): sale_order.approval_status = 'pengajuan1' return self.response('success') - + @http.route(PREFIX_PARTNER + 'sale_order/<id>/reject', auth='public', method=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized(private=True, private_key='partner_id') def partner_reject_sale_order_by_id(self, **kw): @@ -356,27 +433,27 @@ class SaleOrder(controller.Controller): 'partner_id': ['number'], 'id': ['number'] }) - + if not params['valid']: return self.response(code=400, description=params) - + value = params['value'] partner_child_ids = self.get_partner_child_ids(value['partner_id']) - + sale_order = request.env['sale.order'].search([ ('id', '=', value['id']), ('partner_id', 'in', partner_child_ids) ]) if not sale_order: return self.response(code=404, description='Sale Order not found') - + partner = request.env['res.partner'].browse(value['partner_id']) if not partner.web_role: return self.response(code=400, description='Unauthorized') - + if partner.web_role: sale_order.web_approval = 'cust_%s' % partner.web_role - + sale_order.state = 'cancel' sale_order.approval_status = False @@ -447,7 +524,7 @@ class SaleOrder(controller.Controller): sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['name']) # pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'quotation_so_new')]).render_jasper([id], {}) pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'indoteknik_custom.report_saleorder_website')])._render_qweb_pdf([id]) - + if pdf and len(sale_order) > 0: return rest_api.response_attachment({ 'content': pdf, @@ -478,27 +555,27 @@ class SaleOrder(controller.Controller): sale_order.state = 'cancel' data = sale_order.id return self.response(data) - + @http.route(prefix + 'user/<user_id>/sale_order/checkout', auth='public', method=['GET', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized(private=True, private_key='user_id') def get_user_checkout_so(self, user_id, **kw): m_voucher = request.env['voucher'] m_cart = request.env['website.user.cart'] - + voucher_code = kw.get('voucher') voucher_shipping_code = kw.get('voucher_shipping') source = kw.get('source') - + voucher = m_voucher.search([('code', '=', voucher_code), ('apply_type', 'in', ['all', 'brand'])], limit=1) voucher_shipping = m_voucher.search([('code', '=', voucher_shipping_code), ('apply_type', '=', 'shipping')], limit=1) result = m_cart.with_context(price_for="web").get_user_checkout( - user_id, - voucher=voucher, - voucher_shipping=voucher_shipping, + user_id, + voucher=voucher, + voucher_shipping=voucher_shipping, source=source ) return self.response(result) - + @http.route(PREFIX_PARTNER + 'sale_order/checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def create_partner_sale_order(self, **kw): @@ -544,7 +621,7 @@ class SaleOrder(controller.Controller): main_partner = partner_invoice.get_main_parent() _logger.info( f"Partner Info - Sales: {sales_partner.id}, Invoice: {partner_invoice.id}, Main: {main_partner.id}") - + def _get_request_context(params, kw): # 1) kw (querystring di route) ctx = kw.get('context') @@ -582,7 +659,7 @@ class SaleOrder(controller.Controller): f"form={repr(request.httprequest.form.get('context'))}, " f"json={(request.httprequest.get_json(force=False, silent=True) or {}).get('context') if hasattr(request.httprequest,'get_json') else None}, " f"normalized={ctx}") - + payment_term_id_value = 26 ctx = str((kw.get('context') or '')) @@ -607,7 +684,7 @@ class SaleOrder(controller.Controller): payment_term_id_value = term.id except Exception as e: _logger.warning(f"Gagal resolve payment term dari user: {e}") - + parameters = { 'warehouse_id': 8, 'carrier_id': 1, @@ -767,7 +844,7 @@ class SaleOrder(controller.Controller): except Exception as e: _logger.error(f"Error in create_partner_sale_order: {str(e)}", exc_info=True) return self.response(code=500, description=str(e)) - + @http.route(PREFIX_PARTNER + 'sale-order/<id>/awb', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized(private=True, private_key='partner_id') def get_airway_bill_by_sale_order_id(self, **kw): @@ -782,8 +859,8 @@ class SaleOrder(controller.Controller): for airway_bill in airway_bills: data = airway_bill.decode_response() delivery_order = airway_bill.do_id - result = data['rajaongkir']['result'] - + result = data['rajaongkir']['result'] + manifests_data = [] for manifest in airway_bill.manifest_ids: manifest_data = { @@ -793,7 +870,7 @@ class SaleOrder(controller.Controller): 'city': manifest.city, } manifests_data.append(manifest_data) - + airways.append({ 'delivery_order': { 'name': delivery_order.name, @@ -801,7 +878,7 @@ class SaleOrder(controller.Controller): 'receiver_name': airway_bill.receiver_name, 'receiver_city': airway_bill.receiver_city, }, - 'delivered': result['delivered'], + 'delivered': result['delivered'], 'waybill_number': result['summary']['waybill_number'], 'delivery_status': result['delivery_status'], 'manifests': manifests_data @@ -809,7 +886,7 @@ class SaleOrder(controller.Controller): response = {'airways': airways} return self.response(response) - + @http.route('/api/sale_order/invoiced', auth='public', methods=['GET']) def get_sale_order_invoiced_by_partner_id(self, **kw): if not self.authenticate(): diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 762e17c5..a4a9cf80 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -124,33 +124,53 @@ class StockPicking(controller.Controller): @http.route(prefix + 'stock-picking/<scanid>/documentation', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() - def write_partner_stock_picking_documentation(self, **kw): - scanid = kw.get('scanid', '').strip() - sj_document = kw.get('sj_document', False) - paket_document = kw.get('paket_document', False) - - params = { - 'sj_documentation': sj_document, - 'paket_documentation': paket_document, - 'driver_arrival_date': datetime.utcnow(), + def write_partner_stock_picking_documentation(self, scanid, **kw): + sj_document = kw.get('sj_document', False) + paket_document = kw.get('paket_document', False) + dispatch_document = kw.get('dispatch_document', False) + + # ===== Role by EMAIL ===== + driver_emails = { + 'driverindoteknik@gmail.com', + 'sulistianaridwan8@gmail.com', } + dispatch_emails = { + 'rahmat.afiudin@gmail.com', + 'it@fixcomart.co.id' + } + + login = (request.env.user.login or '').lower() + is_dispatch_user = login in dispatch_emails + is_driver_user = (login in driver_emails) and not is_dispatch_user + + # ===== Validasi minimal ===== + if not sj_document or not paket_document: + return self.response(code=400, description='dispatch_document wajib untuk role dispatch login= %s' % login) + # if is_dispatch_user and not dispatch_document and not is_driver_user: + # return self.response(code=400, description='dispatch_document wajib untuk role dispatch login= %s' % login) + + # ===== Cari picking by id / picking_code ===== picking_data = False - if scanid.isdigit() and int(scanid) < 2147483647: - picking_data = request.env['stock.picking'].search([('id', '=', int(scanid))], limit=1) + if scanid.isdigit() and int(scanid) < 2147483646: + picking_data = request.env['stock.picking'].search([('id', '=', int(scanid))], limit=0) if not picking_data: - picking_data = request.env['stock.picking'].search([('picking_code', '=', scanid)], limit=1) + picking_data = request.env['stock.picking'].search([('picking_code', '=', scanid)], limit=0) if not picking_data: - return self.response(code=404, description='picking not found') - - picking_data.write(params) + return self.response(code=403, description='picking not found') - return self.response({ - 'name': picking_data.name - }) + params = { + 'sj_documentation': sj_document, + 'paket_documentation': paket_document, + 'driver_arrival_date': datetime.utcnow(), + } + if dispatch_document: + params['dispatch_documentation'] = dispatch_document + picking_data.write(params) + return self.response({'name': picking_data.name}) @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False) def update_status_from_biteship(self, **kw): @@ -160,7 +180,7 @@ class StockPicking(controller.Controller): # Karena type='json', Odoo secara otomatis akan mem-parsing JSON untuk Anda. # 'data' akan berisi dictionary Python dari payload JSON Biteship. data = request.jsonrequest - + # Log ini akan menunjukkan payload yang diterima (sudah dalam bentuk dict) _logger.info(f"Biteship Webhook: Parsed JSON data from request.jsonrequest: {json.dumps(data)}") diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index dde30fec..3511bc52 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -89,7 +89,9 @@ class User(controller.Controller): 'name': name, 'login': email, 'oauth_provider_id': request.env.ref('auth_oauth.provider_google').id, - 'sel_groups_1_9_10': 9 + 'sel_groups_1_9_10': 9, + 'active': True, + } user = request.env['res.users'].create(user_data) |
