diff options
| -rw-r--r-- | indoteknik_api/controllers/api_v1/stock_picking.py | 12 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 57 | ||||
| -rw-r--r-- | indoteknik_custom/views/stock_picking.xml | 18 |
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"/> |
