summaryrefslogtreecommitdiff
path: root/indoteknik_api/controllers/api_v1
diff options
context:
space:
mode:
Diffstat (limited to 'indoteknik_api/controllers/api_v1')
-rw-r--r--indoteknik_api/controllers/api_v1/cart.py35
-rw-r--r--indoteknik_api/controllers/api_v1/partner.py186
-rw-r--r--indoteknik_api/controllers/api_v1/product.py114
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py4
-rw-r--r--indoteknik_api/controllers/api_v1/state.py10
-rw-r--r--indoteknik_api/controllers/api_v1/stock_picking.py174
6 files changed, 342 insertions, 181 deletions
diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py
index 7a40b1e2..fdc237cf 100644
--- a/indoteknik_api/controllers/api_v1/cart.py
+++ b/indoteknik_api/controllers/api_v1/cart.py
@@ -16,24 +16,31 @@ class Cart(controller.Controller):
offset = int(kw.get('offset', 0))
query = [('user_id', '=', user_id)]
carts = user_cart.search(query, limit=limit, offset=offset, order='create_date desc')
- # carts.write({'source': 'add_to_cart'})
+
products = []
products_inactive = []
+
for cart in carts:
- if cart.product_id:
- price = cart.product_id._v2_get_website_price_include_tax()
- if cart.product_id.active and price > 0:
- product = cart.with_context(price_for="web").get_products()
- for product_active in product:
- products.append(product_active)
+ try:
+ if cart.product_id:
+ price = cart.product_id._v2_get_website_price_include_tax()
+
+ if cart.product_id.active and price > 0:
+ product = cart.with_context(price_for="web").get_products()
+ for product_active in product:
+ products.append(product_active)
+ else:
+ product_inactives = cart.with_context(price_for="web").get_products()
+ for inactives in product_inactives:
+ products_inactive.append(inactives)
else:
- product_inactives = cart.with_context(price_for="web").get_products()
- for inactives in product_inactives:
- products_inactive.append(inactives)
- else:
- program = cart.with_context(price_for="web").get_products()
- for programs in program:
- products.append(programs)
+ program = cart.with_context(price_for="web").get_products()
+ for programs in program:
+ products.append(programs)
+
+ except Exception as e:
+ continue
+
data = {
'product_total': user_cart.search_count(query),
'products': products,
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py
index 126fded4..b8bd21be 100644
--- a/indoteknik_api/controllers/api_v1/partner.py
+++ b/indoteknik_api/controllers/api_v1/partner.py
@@ -1,6 +1,6 @@
from .. import controller
from odoo import http
-from odoo.http import request
+from odoo.http import request, Response
from odoo import fields
import json
import base64
@@ -61,46 +61,48 @@ class Partner(controller.Controller):
partner = request.env['res.users'].api_address_response(partner)
return self.response(partner)
- @http.route(prefix + 'partner/<id>/address', auth='public', methods=['PUT', 'OPTIONS'], csrf=False)
+ @http.route(prefix + 'partner/<id>/address', type="json", auth='public', methods=['PUT', 'OPTIONS'], csrf=False, cors='*')
@controller.Controller.must_authorized()
- def write_partner_address_by_id(self, **kw):
+ def write_partner_address_by_id(self, id, **kw):
+ headers = {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers': '*'
+ }
+ if request.httprequest.method == 'OPTIONS':
+ return Response(status=200, headers=headers)
try:
- params = self.get_request_params(kw, {
- 'id': ['required', 'number'],
- 'type': ['default:other'],
- 'name': ['required'],
- 'email': ['required'],
- 'mobile': ['required'],
- 'phone': [''],
- 'street': ['required'],
- 'state_id': ['required', 'number', 'alias:state_id'],
- 'city_id': ['required', 'number', 'alias:kota_id'],
- 'district_id': ['number', 'alias:kecamatan_id'],
- 'sub_district_id': ['number', 'alias:kelurahan_id', 'exclude_if_null'],
- 'zip': ['required'],
- 'longtitude': '',
- 'latitude': '',
- 'address_map': [],
- 'alamat_lengkap_text': []
- })
+ params = self.get_request_params(request.jsonrequest, {
+ 'id': ['required', 'number'],
+ 'type': ['default:other'],
+ 'name': ['required'],
+ 'email': ['required'],
+ 'mobile': ['required'],
+ 'phone': [''],
+ 'street': ['required'],
+ 'state_id': ['required', 'alias:state_id'],
+ 'city_id': ['required', 'alias:kota_id'],
+ 'district_id': ['alias:kecamatan_id'],
+ 'sub_district_id': ['alias:kelurahan_id', 'exclude_if_null'],
+ 'zip': ['required'],
+ 'longtitude': '',
+ 'latitude': '',
+ 'address_map': [],
+ 'alamat_lengkap_text': []
+ })
if not params['valid']:
- return self.response(code=400, description=params)
-
- partner = request.env[self._name].sudo().search([('id', '=', params['value']['id'])], limit=1)
+ return {'headers' : headers,'code': 400, 'description': params}
+ partner = request.env['res.partner'].sudo().search([('id', '=', id)], limit=1)
if not partner:
- return self.response(code=404, description='User not found')
-
- try:
- partner.write(params['value'])
- except Exception as e:
- return self.response(code=500, description=f'Error writing partner data: {str(e)}')
+ return {'headers' : headers,'code': 404, 'description': 'User not found'}
- return self.response({'id': partner.id})
+ partner.write(params['value'])
+ return {'id': partner.id, 'headers' : headers}
except Exception as e:
- return self.response(code=500, description=f'Unexpected error: {str(e)}')
+ return {'headers' : headers,'code': 500, 'description': f'Internal Error: {str(e)}'}
@http.route(prefix + 'partner/address', auth='public', methods=['POST', 'OPTIONS'], csrf=False)
@controller.Controller.must_authorized()
@@ -132,69 +134,83 @@ class Partner(controller.Controller):
'id': partner.id,
})
- @http.route(prefix + 'partner/<id>', auth='public', methods=['PUT', 'OPTIONS'], csrf=False)
+ @http.route(prefix + 'partner/<int:id>', auth='public', methods=['POST', 'OPTIONS'], csrf=False)
@controller.Controller.must_authorized()
- def write_partner_by_id(self, **kw):
- params = self.get_request_params(kw, {
- 'id': ['', 'number'],
- 'name': [],
- 'company_type_id': ['number'],
- 'industry_id': ['number'],
- 'tax_name': ['alias:nama_wajib_pajak'],
- 'npwp': [],
- 'alamat_lengkap_text': [],
- 'street': [],
- 'email': [],
- 'mobile': []
- })
- id_user = self.get_request_params(kw, {
- 'id_user': ['number']
- })
- params_user = self.get_request_params(kw, {
- 'company_type_id': ['number'],
- 'industry_id': ['number'],
- 'tax_name': ['alias:nama_wajib_pajak'],
- 'npwp': [],
- 'alamat_lengkap_text': [],
- })
+ def write_partner_by_id(self, id, **kw):
+ try:
+ # Ambil data JSON langsung
+ request_data = kw
+
+ partner = request.env['res.partner'].sudo().browse(id)
+ if not partner.exists():
+ return self.response({
+ 'code': 400,
+ 'description': 'Partner not found'
+ })
- if not params['valid']:
- return self.response(code=400, description=params)
+ partner_params = self.get_request_params(request_data, {
+ 'tax_name': ['alias:nama_wajib_pajak'],
+ 'company_type_id': ['number'],
+ 'industry_id': ['number'],
+ 'npwp': [],
+ 'alamat_lengkap_text': [],
+ 'street': [],
+ 'email': [],
+ 'mobile': []
+ })
- partner = request.env[self._name].search([('id', '=', params['value']['id'])], limit=1)
- user = request.env[self._name].search([('id', '=', id_user['value']['id_user'])], limit=1)
- if not partner:
- return self.response(code=404, description='Partner not found')
+ if not partner_params['valid']:
+ return self.response({
+ 'code': 400,
+ 'description': partner_params
+ })
- if not params['value'].get('tax_name'):
- params['value']['nama_wajib_pajak'] = params['value'].get('name')
- params_user['value']['nama_wajib_pajak'] = params_user['value'].get('name')
+ partner_values = partner_params['value']
- if not params['value'].get('alamat_lengkap_text'):
- params['value']['alamat_lengkap_text'] = params['value'].get('street')
- params_user['value']['alamat_lengkap_text'] = params_user['value'].get('street')
+ if 'id_user' in request_data:
+ user_params = self.get_request_params(request_data, {
+ 'id_user': ['required', 'number'],
+ 'company_type_id': ['number'],
+ 'industry_id': ['number'],
+ 'tax_name': ['alias:nama_wajib_pajak'],
+ 'npwp': [],
+ 'alamat_lengkap_text': [],
+ })
- if not params['value'].get('npwp'):
- params['value']['npwp'] = "00.000.000.0-000.000"
- params_user['value']['npwp'] = "00.000.000.0-000.000"
+ if not user_params['valid']:
+ return self.response({
+ 'code': 400,
+ 'description': user_params
+ })
- # Filter parameter yang memiliki nilai saja untuk partner
- params_filtered = {k: v for k, v in params['value'].items() if v}
+ user = request.env['res.partner'].sudo().browse(int(user_params['value']['id_user']))
+ if user.exists():
+ user_values = user_params['value']
- # Filter parameter yang memiliki nilai saja untuk user
- params_user_filtered = {k: v for k, v in params_user['value'].items() if v}
+ if not user_values.get('tax_name'):
+ user_values['nama_wajib_pajak'] = user_values.get('name', user.name)
- # Update partner dan user hanya dengan parameter yang memiliki nilai
- if params_filtered:
- partner.write(params_filtered)
+ if not user_values.get('alamat_lengkap_text'):
+ user_values['alamat_lengkap_text'] = user_values.get('street', user.street)
- if params_user_filtered:
- user.write(params_user_filtered)
+ if not user_values.get('npwp'):
+ user_values['npwp'] = "00.000.000.0-000.000"
- # Return response dengan ID partner yang di-update
- return self.response({
- 'id': partner.id
- })
+ user_values_filtered = {k: v for k, v in user_values.items() if k != 'id_user' and v is not None}
+ if user_values_filtered:
+ user.write(user_values_filtered)
+
+ partner.write(partner_values)
+
+ return self.response({
+ 'partner_id': partner.id
+ })
+
+ except Exception as e:
+ return self.response({
+ 'code': 500,
+ 'description': f'Internal Error: {str(e)}'
+ })
@http.route(prefix + 'partner/industry', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
@@ -306,7 +322,7 @@ class Partner(controller.Controller):
data = True if pengajuan_tempo.id else False
return self.response(data)
- @http.route(prefix + 'partner/pengajuan_tempo', auth='public', methods=['POST'], csrf=False)
+ @http.route(prefix + 'partner/pengajuan_tempo', auth='public', methods=['POST', 'OPTIONS'], csrf=False)
@controller.Controller.must_authorized()
def write_pengajuan_tempo(self, **kw):
try:
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
index a88c3368..e97a7ff8 100644
--- a/indoteknik_api/controllers/api_v1/product.py
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -2,6 +2,7 @@ from .. import controller
from odoo import http
from odoo.http import request, Response
from datetime import datetime, timedelta
+import pytz
import ast
import logging
import math
@@ -46,12 +47,15 @@ class Product(controller.Controller):
('product_id', 'in', product_ids),
('is_winner', '=', True)
])
+ jakarta = pytz.timezone("Asia/Jakarta")
+ start_date = datetime.now(jakarta)
+
+ offset, is3pm = request.env['sale.order'].get_days_until_next_business_day(start_date)
+ additional_days = offset
- start_date = datetime.today().date()
- additional_days = request.env['sale.order'].get_days_until_next_business_day(start_date)
include_instant = True
- if(len(products) != len(product_ids)):
+ if(len(products) == len(product_ids)):
products_data_params = {product["id"] : product for product in product_data }
all_fast_products = all(
@@ -63,8 +67,8 @@ class Product(controller.Controller):
return self.response({
'include_instant': include_instant,
'sla_duration': 1,
- 'sla_additional_days': additional_days,
- 'sla_total' : int(1) + int(additional_days),
+ 'sla_additional_days': int(additional_days),
+ 'sla_total' : int(additional_days),
'sla_unit': 'Hari'
})
@@ -96,27 +100,40 @@ class Product(controller.Controller):
})
@http.route(prefix + 'product_variant/<id>/stock', auth='public', methods=['GET', 'OPTIONS'])
- @controller.Controller.must_authorized()
+ @controller.Controller.must_authorized()
def get_product_template_stock_by_id(self, **kw):
id = int(kw.get('id'))
date_7_days_ago = datetime.now() - timedelta(days=7)
- product = request.env['product.product'].search(
- [('id', '=', id)], limit=1)
- product_sla = request.env['product.sla'].search(
- [('product_variant_id', '=', id)], limit=1)
+ product_pruchase = request.env['purchase.pricelist'].search([
+ ('product_id', '=', id),
+ ('is_winner', '=', True)
+ ])
stock_vendor = request.env['stock.vendor'].search([
('product_variant_id', '=', id),
('write_date', '>=', date_7_days_ago.strftime("%Y-%m-%d %H:%M:%S"))
], limit=1)
+
+ product = product_pruchase.product_id
+
+ vendor_sla = request.env['vendor.sla'].search([('id_vendor', '=', product_pruchase.vendor_id.id)], limit=1)
+ slatime = 15
+ if vendor_sla:
+ if vendor_sla.unit == 'hari':
+ vendor_duration = vendor_sla.duration * 24 * 60
+ else :
+ vendor_duration = vendor_sla.duration * 60
+
+ estimation_sla = (1 * 24 * 60) + vendor_duration
+ estimation_sla_days = estimation_sla / (24 * 60)
+ slatime = math.ceil(estimation_sla_days)
qty_available = product.qty_free_bandengan
-
if qty_available < 1 :
qty_available = 0
qty = 0
- sla_date = '-'
+ sla_date = f'{slatime} Hari'
# Qty Stock Vendor
qty_vendor = stock_vendor.quantity
@@ -136,28 +153,89 @@ class Product(controller.Controller):
if qty_available > 0:
qty = qty_available + total_adem + total_excell
- sla_date = product_sla.sla or 1
+ sla_date = '1 Hari'
elif qty_altama > 0 or qty_vendor > 0:
qty = total_adem if qty_altama > 0 else total_excell
- sla_date = product_sla.sla
+ sla_date = f'{slatime} Hari'
else:
- sla_date = product_sla.sla
+ sla_date = f'{slatime} Hari'
except:
print('error')
else:
if qty_available > 0:
qty = qty_available
- sla_date = product_sla.sla or 'Indent'
+ sla_date = f'1 Hari'
elif qty_vendor > 0:
qty = total_excell
- sla_date = '2-4 Hari'
+ sla_date = f'{slatime} Hari'
data = {
'qty': qty,
'sla_date': sla_date
}
- return self.response(data, headers=[('Cache-Control', 'max-age=600, private')])
+ return self.response(data, headers=[('Cache-Control', 'max-age=600, private')])
+ # def get_product_template_stock_by_id(self, **kw):
+ # id = int(kw.get('id'))
+ # date_7_days_ago = datetime.now() - timedelta(days=7)
+ # product = request.env['product.product'].search(
+ # [('id', '=', id)], limit=1)
+ # product_sla = request.env['product.sla'].search(
+ # [('product_variant_id', '=', id)], limit=1)
+ # stock_vendor = request.env['stock.vendor'].search([
+ # ('product_variant_id', '=', id),
+ # ('write_date', '>=', date_7_days_ago.strftime("%Y-%m-%d %H:%M:%S"))
+ # ], limit=1)
+
+ # qty_available = product.qty_free_bandengan
+
+
+ # if qty_available < 1 :
+ # qty_available = 0
+
+ # qty = 0
+ # sla_date = '-'
+
+ # # Qty Stock Vendor
+ # qty_vendor = stock_vendor.quantity
+ # qty_vendor -= int(qty_vendor * 0.1)
+ # qty_vendor = math.ceil(float(qty_vendor))
+ # total_excell = qty_vendor
+
+ # is_altama_product = product.x_manufacture.id in [10, 122, 89]
+ # if is_altama_product:
+ # try:
+ # # Qty Altama
+ # qty_altama = request.env['product.template'].get_stock_altama(
+ # product.default_code)
+ # qty_altama -= int(qty_altama * 0.1)
+ # qty_altama = math.ceil(float(qty_altama))
+ # total_adem = qty_altama
+
+ # if qty_available > 0:
+ # qty = qty_available + total_adem + total_excell
+ # sla_date = product_sla.sla or 1
+ # elif qty_altama > 0 or qty_vendor > 0:
+ # qty = total_adem if qty_altama > 0 else total_excell
+ # sla_date = product_sla.sla
+ # else:
+ # sla_date = product_sla.sla
+ # except:
+ # print('error')
+ # else:
+ # if qty_available > 0:
+ # qty = qty_available
+ # sla_date = product_sla.sla or 'Indent'
+ # elif qty_vendor > 0:
+ # qty = total_excell
+ # sla_date = '2-4 Hari'
+
+ # data = {
+ # 'qty': qty,
+ # 'sla_date': sla_date
+ # }
+
+ # return self.response(data, headers=[('Cache-Control', 'max-age=600, private')])
@http.route(prefix + 'product_variant/<id>/qty_available', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index e87b357e..3ecaff57 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -521,7 +521,7 @@ class SaleOrder(controller.Controller):
if params['value']['type'] == 'sale_order':
parameters['approval_status'] = 'pengajuan1'
- sale_order = request.env['sale.order'].create([parameters])
+ sale_order = request.env['sale.order'].with_context(from_website_checkout=True).create([parameters])
sale_order.onchange_partner_contact()
user_id = params['value']['user_id']
@@ -540,6 +540,7 @@ class SaleOrder(controller.Controller):
'product_available_quantity': cart['available_quantity']
})
order_line.product_id_change()
+ order_line.weight = order_line.product_id.weight
order_line.onchange_vendor_id()
order_line.price_unit = cart['price']['price']
order_line.discount = cart['price']['discount_percentage']
@@ -575,6 +576,7 @@ class SaleOrder(controller.Controller):
elif sale_order._requires_approval_margin_manager():
sale_order.approval_status = 'pengajuan1'
# user_cart.browse(cart_ids).unlink()
+ sale_order._auto_set_shipping_from_website()
return self.response({
'id': sale_order.id,
'name': sale_order.name
diff --git a/indoteknik_api/controllers/api_v1/state.py b/indoteknik_api/controllers/api_v1/state.py
index 958359a7..c03042e7 100644
--- a/indoteknik_api/controllers/api_v1/state.py
+++ b/indoteknik_api/controllers/api_v1/state.py
@@ -8,12 +8,8 @@ class District(controller.Controller):
@http.route(prefix + 'state', auth='public', methods=['GET', 'OPTIONS'])
@controller.Controller.must_authorized()
def get_state(self, **kw):
- tempo = kw.get('tempo')
- parameters = []
- if tempo == 'true':
- parameters.append(('country_id', '=', 100))
+ parameters = [('country_id', '=', 100)] # selalu ambil country_id = 100
-
name = kw.get('name')
if name:
name = '%' + name.replace(' ', '%') + '%'
@@ -22,7 +18,7 @@ class District(controller.Controller):
states = request.env['res.country.state'].search(parameters)
data = []
for state in states:
- data.append({ 'id': state.id, 'name': state.name})
-
+ data.append({'id': state.id, 'name': state.name})
+
return self.response(data)
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py
index 31706b99..85b0fbba 100644
--- a/indoteknik_api/controllers/api_v1/stock_picking.py
+++ b/indoteknik_api/controllers/api_v1/stock_picking.py
@@ -1,9 +1,14 @@
from .. import controller
from odoo import http
-from odoo.http import request
+from odoo.http import request, Response
from pytz import timezone
from datetime import datetime
+import json
+import logging
+_logger = logging.getLogger(__name__)
+
+_logger = logging.getLogger(__name__)
class StockPicking(controller.Controller):
prefix = '/api/v1/'
@@ -22,42 +27,44 @@ class StockPicking(controller.Controller):
if not get_params['valid']:
return self.response(code=400, description=get_params)
-
+
params = get_params['value']
partner_id = params['partner_id']
limit = params['limit']
offset = params['offset']
-
+
child_ids = request.env['res.partner'].browse(partner_id).get_child_ids()
pending_domain = [('driver_departure_date', '=', False), ('driver_arrival_date', '=', False)]
shipment_domain = [('driver_departure_date', '!=', False), ('driver_arrival_date', '=', False)]
shipment_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '=', False)]
- completed_domain = [('driver_departure_date', '!=', False),'|', ('driver_arrival_date', '!=', False), ('sj_return_date', '!=', False)]
+ completed_domain = [('driver_departure_date', '!=', False), '|', ('driver_arrival_date', '!=', False),
+ ('sj_return_date', '!=', False)]
completed_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '!=', False)]
picking_model = request.env['stock.picking']
domain = [
- ('partner_id', 'in', child_ids),
- ('sale_id', '!=', False),
- ('origin', 'ilike', 'SO%'),
- ('state', '!=', 'cancel')
+ ('partner_id', 'in', child_ids),
+ ('sale_id', '!=', False),
+ ('origin', 'ilike', 'SO%'),
+ ('state', '!=', 'cancel'),
+ ('name', 'ilike', 'BU/OUT%')
]
-
+
if params['q']:
query_like = '%' + params['q'].replace(' ', '%') + '%'
- domain += ['|', '|',
- ('name', 'ilike', query_like),
- ('sale_id.client_order_ref', 'ilike', query_like),
- ('delivery_tracking_no', 'ilike', query_like)
- ]
+ domain += ['|', '|',
+ ('name', 'ilike', query_like),
+ ('sale_id.client_order_ref', 'ilike', query_like),
+ ('delivery_tracking_no', 'ilike', query_like)
+ ]
default_domain = domain.copy()
-
+
if params['status'] == 'pending':
domain += pending_domain
elif params['status'] == 'shipment':
- domain += shipment_domain + shipment_domain2
+ domain += shipment_domain + shipment_domain2
elif params['status'] == 'completed':
domain += completed_domain
@@ -65,7 +72,7 @@ class StockPicking(controller.Controller):
res_pickings = []
for picking in stock_pickings:
manifests = picking.get_manifests()
-
+
res_pickings.append({
'id': picking.id,
'name': picking.name,
@@ -86,12 +93,12 @@ class StockPicking(controller.Controller):
'summary': {
'pending_count': picking_model.search_count(default_domain + pending_domain),
'shipment_count': picking_model.search_count(default_domain + shipment_domain + shipment_domain2),
- 'completed_count': picking_model.search_count(default_domain + completed_domain )
+ 'completed_count': picking_model.search_count(default_domain + completed_domain)
},
'picking_total': picking_model.search_count(domain),
'pickings': res_pickings
})
-
+
@http.route(PREFIX_PARTNER + 'stock-picking/<id>/tracking', auth='public', method=['GET', 'OPTIONS'])
@controller.Controller.must_authorized(private=True, private_key='partner_id')
def get_partner_stock_picking_detail_tracking(self, **kw):
@@ -101,7 +108,6 @@ class StockPicking(controller.Controller):
picking = picking_model.browse(id)
if not picking:
return self.response(None)
- hostori = picking.get_tracking_detail()
return self.response(picking.get_tracking_detail())
@http.route(prefix + 'stock-picking/<id>/tracking', auth='public', method=['GET', 'OPTIONS'])
@@ -140,49 +146,105 @@ class StockPicking(controller.Controller):
return self.response({
'name': picking_data.name
})
-
- @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False)
- def udpate_status_from_bitehsip(self, **kw):
+
+ @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False)
+ def update_status_from_biteship(self, **kw):
+ _logger.info("Biteship Webhook: Request received at controller start (type='json').")
+
try:
- if not request.jsonrequest:
- return "ok"
+ # Karena type='json', Odoo secara otomatis akan mem-parsing JSON untuk Anda.
+ # 'data' akan berisi dictionary Python dari payload JSON Biteship.
+ data = request.jsonrequest
- data = request.jsonrequest # Ambil data JSON dari request
- event = data.get('event')
+ # 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)}")
- # Handle Event Berdasarkan Jenisnya
- if event == "order.status":
- self.process_order_status(data)
- elif event == "order.price":
- self.process_order_price(data)
- elif event == "order.waybill_id":
- self.process_order_waybill(data)
+ event = data.get('event')
+ if event:
+ _logger.info(f"Biteship Webhook: Processing event: {event}")
+ if event == "order.status":
+ self.process_order_status(data)
+ elif event == "order.price":
+ self.process_order_price(data)
+ elif event == "order.waybill_id":
+ self.process_order_waybill(data)
+ # Tambahkan logika untuk event lain jika ada
+ else:
+ _logger.info("Biteship Webhook: No specific event in payload. Likely an installation/verification ping or unknown event type.")
+
+ # Untuk route type='json', Anda cukup mengembalikan dictionary Python.
+ # Odoo akan secara otomatis mengonversinya menjadi respons JSON yang valid.
+ return {'status': 'ok'}
- return {'success': True, 'message': f'Webhook {event} received'}
except Exception as e:
- return {'success': False, 'message': str(e)}
+ _logger.error(f"Biteship Webhook: Unhandled error during processing: {e}", exc_info=True)
+ # Untuk error, kembalikan dictionary error juga, Odoo akan mengonversinya ke JSON
+ return {'status': 'error', 'message': str(e)}
def process_order_status(self, data):
- picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1)
- if data.get('status') == 'picked':
- picking_model.write({'driver_departure_date': datetime.utcnow()})
- elif data.get('status') == 'delivered':
- picking_model.write({'driver_arrival_date': datetime.utcnow()})
-
+ picking = request.env['stock.picking'].sudo().search([
+ ('biteship_id', '=', data.get('order_id'))
+ ], limit=1)
+
+ if not picking:
+ _logger.warning(f"[Webhook] Tidak ditemukan picking untuk order_id {data.get('order_id')}")
+ return
+
+ status = data.get('status')
+ timestamp = data.get('updated_at') or datetime.utcnow().isoformat()
+
+ description = picking._get_biteship_status_description(status, {
+ "courier": {"company": data.get("courier_company", "")},
+ "destination": {"contact_name": picking.partner_id.name or ""}
+ })
+
+ # Tambahkan extra data dari webhook
+ extra_data = {
+ "courier_driver_name": data.get("courier_driver_name"),
+ "courier_driver_phone": data.get("courier_driver_phone"),
+ "courier_driver_plate_number": data.get("courier_driver_plate_number"),
+ "courier_link": data.get("courier_link"),
+ "order_price": data.get("order_price"),
+ "status": data.get("status"),
+ }
+
+ picking.log_biteship_event_from_webhook(status, timestamp, description, extra_data=extra_data)
+
+
+
def process_order_price(self, data):
- picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1)
- order = request.env['sale.order'].sudo().search([('name', '=', picking_model.sale_id.name)], limit=1)
- if order:
- order.write({
- 'delivery_amt': data.get('price')
- })
+ picking = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1)
+
+ if not picking:
+ _logger.warning(f"Tidak ditemukan picking untuk order_id {data.get('order_id')}")
+ return
+
+ picking.log_biteship_event_from_webhook(
+ status='order.price',
+ timestamp=data.get('updated_at') or datetime.utcnow().isoformat(),
+ description='Biaya pengiriman telah diperbarui berdasarkan informasi terbaru dari Biteship.',
+ extra_data={
+ "order_price": data.get("price")
+ }
+ )
+
def process_order_waybill(self, data):
- picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1)
- if picking_model:
- picking_model.write({
- 'biteship_waybill_id': data.get('courier_waybill_id'),
- 'delivery_tracking_no': data.get('courier_waybill_id'),
- 'biteship_tracking_id':data.get('courier_tracking_id')
- })
- \ No newline at end of file
+ picking = request.env['stock.picking'].sudo().search([
+ ('biteship_id', '=', data.get('order_id'))
+ ], limit=1)
+
+ if not picking:
+ _logger.warning(f"Tidak ditemukan picking untuk order_id {data.get('order_id')}")
+ return
+
+ picking.log_biteship_event_from_webhook(
+ status='order.waybill_id',
+ timestamp=data.get('updated_at') or datetime.utcnow().isoformat(),
+ description="Nomor waybill dan tracking diperbarui melalui Biteship.",
+ extra_data={
+ "tracking_id": data.get("courier_tracking_id"),
+ "waybill_id": data.get("courier_waybill_id")
+ }
+ )
+