summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIndoteknik . <it@fixcomart.co.id>2025-06-21 11:02:58 +0700
committerIndoteknik . <it@fixcomart.co.id>2025-06-21 11:02:58 +0700
commit47f83eefa28e7902c4f91c03ac6cd2f71a56e67d (patch)
tree82639c95c108aa212a4e3b0144f4fe51200bd620
parent6e8591a6bd28c4faafc08eb9c539fe24bdecf419 (diff)
(andri) penyesuaian informasi delivery (biteship) pada BU OUT
-rw-r--r--indoteknik_api/controllers/api_v1/stock_picking.py12
-rw-r--r--indoteknik_custom/models/stock_picking.py57
-rw-r--r--indoteknik_custom/views/stock_picking.xml18
3 files changed, 76 insertions, 11 deletions
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py
index 09d0c585..9b2b5fe1 100644
--- a/indoteknik_api/controllers/api_v1/stock_picking.py
+++ b/indoteknik_api/controllers/api_v1/stock_picking.py
@@ -209,7 +209,17 @@ class StockPicking(controller.Controller):
"destination": {"contact_name": picking.partner_id.name or ""}
})
- picking.log_biteship_event_from_webhook(status, timestamp, description)
+ # 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)
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):
diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml
index 22e6cf60..5e33e4c7 100644
--- a/indoteknik_custom/views/stock_picking.xml
+++ b/indoteknik_custom/views/stock_picking.xml
@@ -192,19 +192,33 @@
<field name="note_logistic"/>
<field name="note_info"/>
<field name="responsible" />
- <field name="carrier_id"/>
+ <field name="carrier_id" attrs="{'invisible': [('select_shipping_option_so', '=', 'biteship')]}" />
<field name="biteship_id" invisible="1"/>
<field name="out_code" attrs="{'invisible': [['out_code', '=', False]]}"/>
<field name="picking_code" attrs="{'invisible': [['picking_code', '=', False]]}"/>
<field name="picking_code" string="Picking code (akan digenerate ketika sudah di-validate)" attrs="{'invisible': [['picking_code', '!=', False]]}"/>
<field name="driver_departure_date" attrs="{'readonly':[('invoice_status', '=', 'invoiced')]}"/>
<field name="driver_arrival_date"/>
- <field name="delivery_tracking_no"/>
+ <field name="delivery_tracking_no" attrs="{'invisible': [('select_shipping_option_so', '=', 'biteship')]}"/>
<field name="driver_id"/>
<field name='sj_return_date'/>
<field name="sj_documentation" widget="image" />
<field name="paket_documentation" widget="image" />
</group>
+ <!-- Biteship Group -->
+ <group attrs="{'invisible': [('select_shipping_option_so', '!=', 'biteship')]}">
+ <field name="delivery_tracking_no" />
+ <field name="shipping_method_so_id"/>
+ <field name="shipping_option_so_id"/>
+ <field name="biteship_shipping_price" readonly="1"/>
+ <field name="currency_id" invisible="1"/>
+ <field name="biteship_shipping_status" readonly="1"/>
+ <field name="biteship_driver_name" readonly="1"/>
+ <field name="biteship_driver_phone" readonly="1"/>
+ <field name="biteship_driver_plate_number" readonly="1"/>
+ <button name="action_open_biteship_tracking" string="Visit Biteship Tracking" type="object"/>
+ </group>
+
<group attrs="{'invisible': [('carrier_id', '!=', 151)]}">
<field name="envio_id" invisible="1"/>
<field name="envio_code"/>