From 6d222cdfb56df09e61cd3add3c3fb328bd9adc7b Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Fri, 20 Jun 2025 14:20:57 +0700 Subject: (andri) patch json agar odoo menerima response kosong dari biteship --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/patch/__init__.py | 1 + indoteknik_custom/models/patch/http_override.py | 46 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 indoteknik_custom/models/patch/__init__.py create mode 100644 indoteknik_custom/models/patch/http_override.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 605d1016..094ac69e 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -151,3 +151,4 @@ from . import account_payment_register from . import stock_inventory from . import sale_order_delay from . import approval_invoice_date +from . import patch diff --git a/indoteknik_custom/models/patch/__init__.py b/indoteknik_custom/models/patch/__init__.py new file mode 100644 index 00000000..051b6537 --- /dev/null +++ b/indoteknik_custom/models/patch/__init__.py @@ -0,0 +1 @@ +from . import http_override \ No newline at end of file diff --git a/indoteknik_custom/models/patch/http_override.py b/indoteknik_custom/models/patch/http_override.py new file mode 100644 index 00000000..e1978edb --- /dev/null +++ b/indoteknik_custom/models/patch/http_override.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +import odoo.http +import json +import logging +from werkzeug.exceptions import BadRequest +import functools + +_logger = logging.getLogger(__name__) + +class CustomJsonRequest(odoo.http.JsonRequest): + def __init__(self, httprequest): + super(odoo.http.JsonRequest, self).__init__(httprequest) + + self.params = {} + request_data_raw = self.httprequest.get_data().decode(self.httprequest.charset) + + self.jsonrequest = {} + if request_data_raw.strip(): + try: + self.jsonrequest = json.loads(request_data_raw) + except ValueError: + msg = 'Invalid JSON data: %r' % (request_data_raw,) + _logger.info('%s: %s (Handled by CustomJsonRequest)', self.httprequest.path, msg) + raise BadRequest(msg) + else: + _logger.info("CustomJsonRequest: Received empty or whitespace-only JSON body. Treating as empty JSON for webhook.") + + self.params = dict(self.jsonrequest.get("params", {})) + self.context = self.params.pop('context', dict(self.session.context)) + + +_original_get_request = odoo.http.Root.get_request + +@functools.wraps(_original_get_request) +def _get_request_override(self, httprequest): + _logger.info("--- DEBUG: !!! _get_request_override IS CALLED !!! ---") + _logger.info(f"--- DEBUG: Request Mimetype: {httprequest.mimetype}, Path: {httprequest.path} ---") + + if httprequest.mimetype in ("application/json", "application/json-rpc"): + _logger.debug("Odoo HTTP: Using CustomJsonRequest for mimetype: %s", httprequest.mimetype) + return CustomJsonRequest(httprequest) + else: + _logger.debug("Odoo HTTP: Using original get_request for mimetype: %s", httprequest.mimetype) + return _original_get_request(self, httprequest) + +odoo.http.Root.get_request = _get_request_override \ No newline at end of file -- cgit v1.2.3 From 6e8591a6bd28c4faafc08eb9c539fe24bdecf419 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Fri, 20 Jun 2025 16:06:00 +0700 Subject: (andri) tracking webhook aktif dan menggantikan peran button sebelumnya --- indoteknik_custom/models/__init__.py | 2 +- indoteknik_custom/models/stock_picking.py | 167 ++++++++++++++++++++---------- 2 files changed, 112 insertions(+), 57 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 094ac69e..3f538e25 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -151,4 +151,4 @@ from . import account_payment_register from . import stock_inventory from . import sale_order_delay from . import approval_invoice_date -from . import patch +# from . import patch diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index eabef37c..7bb881c2 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1721,15 +1721,15 @@ class StockPicking(models.Model): response = requests.get(_biteship_url + '/trackings/' + self.biteship_tracking_id, headers=headers, json=manifests) result = response.json() - description = { - 'confirmed' : 'Indoteknik telah melakukan permintaan pick-up', - 'allocated' : 'Kurir akan melakukan pick-up pesanan', - 'picking_up' : 'Kurir sedang dalam perjalanan menuju lokasi pick-up', - 'picked' : 'Pesanan sudah di pick-up kurir '+result.get("courier", {}).get("company", ""), - 'on_hold' : 'Pesanan ditahan sementara karena masalah pengiriman', - 'dropping_off' : 'Kurir sudah ditugaskan dan pesanan akan segera diantar ke pembeli', - 'delivered' : f'Pesanan telah sampai dan diterima oleh {result.get("destination", {}).get("contact_name", "")}' - } + # description = { + # 'confirmed' : 'Indoteknik telah melakukan permintaan pick-up', + # 'allocated' : 'Kurir akan melakukan pick-up pesanan', + # 'picking_up' : 'Kurir sedang dalam perjalanan menuju lokasi pick-up', + # 'picked' : 'Pesanan sudah di pick-up kurir '+result.get("courier", {}).get("company", ""), + # 'on_hold' : 'Pesanan ditahan sementara karena masalah pengiriman', + # 'dropping_off' : 'Kurir sudah ditugaskan dan pesanan akan segera diantar ke pembeli', + # 'delivered' : f'Pesanan telah sampai dan diterima oleh {result.get("destination", {}).get("contact_name", "")}' + # } if (result.get('success') == True): history = result.get("history", []) status = result.get("status", "") @@ -1738,7 +1738,7 @@ class StockPicking(models.Model): manifests.append({ "status": re.sub(r'[^a-zA-Z0-9\s]', ' ', entry["status"]).lower().capitalize(), "datetime": self._convert_to_local_time(entry["updated_at"]), - "description": description[entry["status"]], + "description": self._get_biteship_status_description(entry["status"], result), }) return { @@ -1754,53 +1754,108 @@ class StockPicking(models.Model): _logger.error(f"Error fetching Biteship order for picking {self.id}: {str(e)}") return { 'error': str(e) } - def action_sync_biteship_tracking(self): - for picking in self: - if not picking.biteship_id: - raise UserError("Tracking Biteship tidak tersedia.") - - histori = picking.get_manifest_biteship() - updated_fields = {} - seen_logs = set() - - manifests = sorted(histori.get("manifests", []), key=lambda m: m.get("datetime") or "") - - for manifest in manifests: - status = manifest.get("status", "").lower() - dt_str = manifest.get("datetime") - desc = manifest.get("description") - dt = False - - try: - dt = picking._convert_to_utc_datetime(dt_str) - _logger.info(f"[Biteship Sync] Berhasil parse datetime: {dt_str} -> {dt}") - except Exception as e: - _logger.warning(f"[Biteship Sync] Gagal parse datetime: {e}") - continue + # def action_sync_biteship_tracking(self): + # for picking in self: + # if not picking.biteship_id: + # raise UserError("Tracking Biteship tidak tersedia.") + + # histori = picking.get_manifest_biteship() + # updated_fields = {} + # seen_logs = set() + + # manifests = sorted(histori.get("manifests", []), key=lambda m: m.get("datetime") or "") + + # for manifest in manifests: + # status = manifest.get("status", "").lower() + # dt_str = manifest.get("datetime") + # desc = manifest.get("description") + # dt = False + + # try: + # dt = picking._convert_to_utc_datetime(dt_str) + # _logger.info(f"[Biteship Sync] Berhasil parse datetime: {dt_str} -> {dt}") + # except Exception as e: + # _logger.warning(f"[Biteship Sync] Gagal parse datetime: {e}") + # continue + + # # Update tanggal ke field (pastikan naive datetime UTC) + # if status == "picked" and dt and not picking.driver_departure_date: + # updated_fields["driver_departure_date"] = fields.Datetime.to_string(dt) + + # if status == "delivered" and dt and not picking.driver_arrival_date: + # updated_fields["driver_arrival_date"] = fields.Datetime.to_string(dt) + + # # Buat log unik dengan waktu lokal Asia/Jakarta + # if dt and desc: + # try: + # dt_local = parser.parse(dt_str).replace(tzinfo=None) + # except Exception as e: + # _logger.warning(f"[Biteship Sync] Gagal parse dt_str untuk log: {e}") + # dt_local = dt # fallback + + # desc_clean = ' '.join(desc.strip().split()) + # log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {desc_clean}" + # if not picking._has_existing_log(log_line): + # picking.message_post(body=log_line) + # seen_logs.add(log_line) + + # if updated_fields: + # picking.write(updated_fields) + + def _get_biteship_status_description(self, status, data=None): + + data = data or {} + + courier = data.get("courier", {}).get("company", "") + contact_name = data.get("destination", {}).get("contact_name", "") + + description_map = { + 'confirmed': 'Indoteknik telah melakukan permintaan pick-up', + 'allocated': 'Kurir akan melakukan pick-up pesanan', + 'picking_up': 'Kurir sedang dalam perjalanan menuju lokasi pick-up', + 'picked': f'Pesanan sudah di pick-up kurir {courier}', + 'on_hold': 'Pesanan ditahan sementara karena masalah pengiriman', + 'dropping_off': 'Kurir sudah ditugaskan dan pesanan akan segera diantar ke pembeli', + 'delivered': f'Pesanan telah sampai dan diterima oleh {contact_name}', + 'cancelled': 'Pesanan dibatalkan oleh sistem atau pengguna', + } + + return description_map.get(status, f"Status '{status}' diterima dari Biteship") + + + def log_biteship_event_from_webhook(self, status, timestamp, description): + self.ensure_one() + updated_fields = {} + + try: + dt = self._convert_to_utc_datetime(timestamp) + except Exception as e: + _logger.warning(f"[Webhook] Gagal konversi waktu: {e}") + dt = datetime.utcnow() + + if status == "picked" and not self.driver_departure_date: + updated_fields["driver_departure_date"] = fields.Datetime.to_string(dt) + if status == "delivered" and not self.driver_arrival_date: + updated_fields["driver_arrival_date"] = fields.Datetime.to_string(dt) + + # Update shipping_status + shipping_status = self._map_status_biteship(status) + if shipping_status and self.shipping_status != shipping_status: + updated_fields["shipping_status"] = shipping_status + + # Log ke chatter + try: + dt_local = parser.parse(timestamp).replace(tzinfo=None) + except Exception: + dt_local = dt + + log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {description.strip()}" + if not self._has_existing_log(log_line): + self.message_post(body=log_line) + + if updated_fields: + self.write(updated_fields) - # Update tanggal ke field (pastikan naive datetime UTC) - if status == "picked" and dt and not picking.driver_departure_date: - updated_fields["driver_departure_date"] = fields.Datetime.to_string(dt) - - if status == "delivered" and dt and not picking.driver_arrival_date: - updated_fields["driver_arrival_date"] = fields.Datetime.to_string(dt) - - # Buat log unik dengan waktu lokal Asia/Jakarta - if dt and desc: - try: - dt_local = parser.parse(dt_str).replace(tzinfo=None) - except Exception as e: - _logger.warning(f"[Biteship Sync] Gagal parse dt_str untuk log: {e}") - dt_local = dt # fallback - - desc_clean = ' '.join(desc.strip().split()) - log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {desc_clean}" - if not picking._has_existing_log(log_line): - picking.message_post(body=log_line) - seen_logs.add(log_line) - - if updated_fields: - picking.write(updated_fields) def _has_existing_log(self, log_line): self.ensure_one() -- cgit v1.2.3 From 47f83eefa28e7902c4f91c03ac6cd2f71a56e67d Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 21 Jun 2025 11:02:58 +0700 Subject: (andri) penyesuaian informasi delivery (biteship) pada BU OUT --- indoteknik_custom/models/stock_picking.py | 57 ++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 7bb881c2..f171c5d0 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -271,15 +271,22 @@ class StockPicking(models.Model): # Biteship Section biteship_id = fields.Char(string="Biteship Respon ID") - biteship_tracking_id = fields.Char(string="Biteship Trackcking ID") + biteship_tracking_id = fields.Char(string="Biteship Tracking ID") biteship_waybill_id = fields.Char(string="Biteship Waybill ID") + biteship_driver_name = fields.Char('Biteship Driver Name') + biteship_driver_phone = fields.Char('Biteship Driver Phone') + biteship_driver_plate_number = fields.Char('Biteship Driver Plate Number') + biteship_courier_link = fields.Char('Biteship Courier Link') + biteship_shipping_status = fields.Char('Biteship Shipping Status', help="Status pengiriman dari Biteship") + biteship_shipping_price = fields.Monetary('Biteship Shipping Price', currency_field='currency_id', help="Harga pengiriman dari Biteship") + currency_id = fields.Many2one('res.currency', related='sale_id.currency_id', string='Currency', readonly=True) final_seq = fields.Float(string='Remaining Time') - shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method SO', related='sale_id.carrier_id') - shipping_option_so_id = fields.Many2one('shipping.option', string='Shipping Option SO', related='sale_id.shipping_option_id') + shipping_method_so_id = fields.Many2one('delivery.carrier', string='Shipping Method', related='sale_id.carrier_id', help="Shipping Method yang digunakan di SO") + shipping_option_so_id = fields.Many2one('shipping.option', string='Shipping Option', related='sale_id.shipping_option_id' , help="Shipping Option yang digunakan di SO") select_shipping_option_so = fields.Selection([ ('biteship', 'Biteship'), ('custom', 'Custom'), - ], string='Shipping Type SO', related='sale_id.select_shipping_option') + ], string='Shipping Type', related='sale_id.select_shipping_option', help="Shipping Type yang digunakan di SO") state_packing = fields.Selection([('not_packing', 'Belum Packing'), ('packing_done', 'Sudah Packing')], string='Packing Status') approval_invoice_date_id = fields.Many2one('approval.invoice.date', string='Approval Invoice Date') last_update_date_doc_kirim = fields.Datetime(string='Last Update Tanggal Kirim', copy=False) @@ -1802,6 +1809,16 @@ class StockPicking(models.Model): # if updated_fields: # picking.write(updated_fields) + def action_open_biteship_tracking(self): + self.ensure_one() + if not self.biteship_courier_link: + raise UserError("Biteship tracking link tidak tersedia.") + return { + 'type': 'ir.actions.act_url', + 'url': self.biteship_courier_link, + 'target': 'new', + } + def _get_biteship_status_description(self, status, data=None): data = data or {} @@ -1823,16 +1840,21 @@ class StockPicking(models.Model): return description_map.get(status, f"Status '{status}' diterima dari Biteship") - def log_biteship_event_from_webhook(self, status, timestamp, description): + def log_biteship_event_from_webhook(self, status, timestamp, description, extra_data=None): + """ + extra_data: dict opsional dari webhook (driver name, phone, plate, link, price, dsb) + """ self.ensure_one() updated_fields = {} + # Konversi timestamp ke UTC datetime try: dt = self._convert_to_utc_datetime(timestamp) except Exception as e: _logger.warning(f"[Webhook] Gagal konversi waktu: {e}") dt = datetime.utcnow() + # Update tanggal driver if status == "picked" and not self.driver_departure_date: updated_fields["driver_departure_date"] = fields.Datetime.to_string(dt) if status == "delivered" and not self.driver_arrival_date: @@ -1843,18 +1865,37 @@ class StockPicking(models.Model): if shipping_status and self.shipping_status != shipping_status: updated_fields["shipping_status"] = shipping_status - # Log ke chatter + # Update field tambahan Biteship jika ada + if extra_data: + if extra_data.get("courier_driver_name"): + updated_fields["biteship_driver_name"] = extra_data["courier_driver_name"] + if extra_data.get("courier_driver_phone"): + updated_fields["biteship_driver_phone"] = extra_data["courier_driver_phone"] + if extra_data.get("courier_driver_plate_number"): + updated_fields["biteship_driver_plate_number"] = extra_data["courier_driver_plate_number"] + if extra_data.get("courier_link"): + updated_fields["biteship_courier_link"] = extra_data["courier_link"] + if extra_data.get("order_price"): + updated_fields["biteship_shipping_price"] = extra_data["order_price"] + if extra_data.get("status"): + updated_fields["biteship_shipping_status"] = extra_data["status"] + + # Format log untuk chatter try: dt_local = parser.parse(timestamp).replace(tzinfo=None) except Exception: dt_local = dt - log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {description.strip()}" + desc_clean = ' '.join(description.strip().split()) + log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {desc_clean}" + if not self._has_existing_log(log_line): - self.message_post(body=log_line) + self.with_user(15172).message_post(body=log_line) + # Apply update if updated_fields: self.write(updated_fields) + _logger.info(f"[Webhook] Updated fields on picking {self.name}: {updated_fields}") def _has_existing_log(self, log_line): -- cgit v1.2.3 From 6b780e717b8fe0b7959bd1a1f6d59b183d9845d9 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 21 Jun 2025 11:21:13 +0700 Subject: (andri) fix datetime log tracking --- indoteknik_custom/models/stock_picking.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f171c5d0..87363fd2 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1841,31 +1841,24 @@ class StockPicking(models.Model): def log_biteship_event_from_webhook(self, status, timestamp, description, extra_data=None): - """ - extra_data: dict opsional dari webhook (driver name, phone, plate, link, price, dsb) - """ self.ensure_one() updated_fields = {} - # Konversi timestamp ke UTC datetime try: dt = self._convert_to_utc_datetime(timestamp) except Exception as e: _logger.warning(f"[Webhook] Gagal konversi waktu: {e}") dt = datetime.utcnow() - # Update tanggal driver if status == "picked" and not self.driver_departure_date: updated_fields["driver_departure_date"] = fields.Datetime.to_string(dt) if status == "delivered" and not self.driver_arrival_date: updated_fields["driver_arrival_date"] = fields.Datetime.to_string(dt) - # Update shipping_status shipping_status = self._map_status_biteship(status) if shipping_status and self.shipping_status != shipping_status: updated_fields["shipping_status"] = shipping_status - # Update field tambahan Biteship jika ada if extra_data: if extra_data.get("courier_driver_name"): updated_fields["biteship_driver_name"] = extra_data["courier_driver_name"] @@ -1880,19 +1873,20 @@ class StockPicking(models.Model): if extra_data.get("status"): updated_fields["biteship_shipping_status"] = extra_data["status"] - # Format log untuk chatter try: - dt_local = parser.parse(timestamp).replace(tzinfo=None) + dt_parsed = parser.parse(timestamp) + if dt_parsed.tzinfo is None: + dt_parsed = dt_parsed.replace(tzinfo=pytz.utc) + dt_local = dt_parsed.astimezone(pytz.timezone("Asia/Jakarta")) except Exception: - dt_local = dt + dt_local = dt.astimezone(pytz.timezone("Asia/Jakarta")) desc_clean = ' '.join(description.strip().split()) - log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}: {desc_clean}" + log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}:
{desc_clean}" if not self._has_existing_log(log_line): self.with_user(15172).message_post(body=log_line) - # Apply update if updated_fields: self.write(updated_fields) _logger.info(f"[Webhook] Updated fields on picking {self.name}: {updated_fields}") -- cgit v1.2.3 From 126774bd23276b80dd67dfb3bcdf3be633f6da86 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 21 Jun 2025 14:18:20 +0700 Subject: (andri) add user biteship live --- indoteknik_custom/models/stock_picking.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 87363fd2..7b5d98a2 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1885,7 +1885,8 @@ class StockPicking(models.Model): log_line = f"[TRACKING] {status} - {dt_local.strftime('%d %b %Y %H:%M')}:
{desc_clean}" if not self._has_existing_log(log_line): - self.with_user(15172).message_post(body=log_line) + self.with_user(15172).message_post(body=log_line) # user biteship test + # self.with_user(15710).message_post(body=log_line) # user biteship live if updated_fields: self.write(updated_fields) -- cgit v1.2.3 From 20f206f3d9b798fee50a06d4a462cf256a71d58e Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 21 Jun 2025 15:49:35 +0700 Subject: (andri) penambahan status tracking --- indoteknik_custom/models/stock_picking.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 7b5d98a2..d4167609 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1820,9 +1820,7 @@ class StockPicking(models.Model): } def _get_biteship_status_description(self, status, data=None): - data = data or {} - courier = data.get("courier", {}).get("company", "") contact_name = data.get("destination", {}).get("contact_name", "") @@ -1831,9 +1829,14 @@ class StockPicking(models.Model): 'allocated': 'Kurir akan melakukan pick-up pesanan', 'picking_up': 'Kurir sedang dalam perjalanan menuju lokasi pick-up', 'picked': f'Pesanan sudah di pick-up kurir {courier}', - 'on_hold': 'Pesanan ditahan sementara karena masalah pengiriman', 'dropping_off': 'Kurir sudah ditugaskan dan pesanan akan segera diantar ke pembeli', 'delivered': f'Pesanan telah sampai dan diterima oleh {contact_name}', + 'return_in_transit': 'Pesanan dalam perjalanan kembali ke pengirim', + 'on_hold': 'Pesanan ditahan sementara karena masalah pengiriman', + 'rejected': 'Pesanan ditolak, silakan hubungi Biteship', + 'courier_not_found': 'Pesanan dibatalkan karena tidak ada kurir tersedia', + 'returned': 'Pesanan berhasil dikembalikan', + 'disposed': 'Pesanan sudah dimusnahkan', 'cancelled': 'Pesanan dibatalkan oleh sistem atau pengguna', } @@ -1941,10 +1944,15 @@ class StockPicking(models.Model): "allocated": "pending", "picking_up": "pending", "picked": "shipment", - "cancelled": "cancelled", - "on_hold": "on_hold", "dropping_off": "shipment", - "delivered": "completed" + "delivered": "completed", + "return_in_transit": "returning", + "on_hold": "on_hold", + "rejected": "cancelled", + "courier_not_found": "cancelled", + "returned": "returned", + "disposed": "disposed", + "cancelled": "cancelled" } return status_mapping.get(status, "Hubungi Admin") -- cgit v1.2.3 From 75fd0f87c6d1f8c3b92450f9826daa74550a5577 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Sat, 5 Jul 2025 15:03:29 +0700 Subject: (andri) info tambahan --- indoteknik_custom/models/stock_picking.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index d25208d1..e411aee6 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1773,6 +1773,7 @@ class StockPicking(models.Model): _logger.error(f"Error fetching Biteship order for picking {self.id}: {str(e)}") return { 'error': str(e) } + # ACTION GET TRACKING MANUAL BITESHIP # def action_sync_biteship_tracking(self): # for picking in self: # if not picking.biteship_id: -- cgit v1.2.3