diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-01-31 16:45:07 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-01-31 16:45:07 +0700 |
| commit | 74796f3390ad90e2ae981351cd0491aca6dccc9c (patch) | |
| tree | afb3765a8878067e9f587664034b2a24de525588 | |
| parent | 346b6dc89cbde3640413714175cdc438544a664c (diff) | |
<iman> add ready to ship date
| -rwxr-xr-x | indoteknik_custom/models/product_template.py | 13 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 57 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 29 | ||||
| -rw-r--r-- | indoteknik_custom/views/product_product.xml | 8 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/stock_picking.xml | 5 |
6 files changed, 109 insertions, 4 deletions
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 5bedae13..8c57774e 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -403,6 +403,19 @@ class ProductProduct(models.Model): merchandise_ok = fields.Boolean(string='Product Promotion') qr_code_variant = fields.Binary("QR Code Variant", compute='_compute_qr_code_variant') + def generate_product_sla(self): + product_variant_ids = self.env.context.get('active_ids', []) + product_variant = self.search([('id', 'in', product_variant_ids)]) + sla_record = self.env['product.sla'].search([('product_variant_id', '=', product_variant.id)], limit=1) + + if sla_record: + sla_record.generate_product_sla() + else: + new_sla_record = self.env['product.sla'].create({ + 'product_variant_id': product_variant.id, + }) + new_sla_record.generate_product_sla() + def _compute_qr_code_variant(self): for rec in self: # Skip inactive variants diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 48195b77..32e6f11f 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -144,6 +144,16 @@ class SaleOrder(models.Model): ('PNR', 'Pareto Non Repeating'), ('NP', 'Non Pareto') ]) + estimated_ready_ship_date = fields.Datetime( + string='ET Ready to Ship', + copy=False, + store=True + ) + expected_ready_ship_date = fields.Datetime( + string='ET Ready to Ship FIX', + copy=False, + store=True + ) @api.onchange('payment_status') def _is_continue_transaction(self): @@ -377,6 +387,45 @@ class SaleOrder(models.Model): else: rec.eta_date = False + def _compute_etrts_date(self): + max_slatime = 100 + + # untuk setiap produk dalam so di ambil sla nya sla paling kecil itulah yang dipakai untuk tambah ke + max_leadtime = 0 + + for line in self.order_line: + product_sla = self.env['product.sla'].search([('product_variant_id', '=', line.product_id.id)]) + slatime = int(product_sla.sla) or 1 + max_slatime = max(max_slatime, slatime) + + for rec in self: + if rec.date_order: + eta_date = datetime.now() + timedelta(days=max_slatime) + rec.estimated_ready_ship_date = eta_date + if not rec.expected_ready_ship_date: + rec.expected_ready_ship_date = eta_date + # else: + # rec.estimated_ready_ship_date = False + + def _set_etrts_date(self): + for order in self: + if order.state in ('done', 'cancel', 'sale'): + raise UserError(_("You cannot change the Estimated Ready To Ship Date on a done, sale or cancelled order.")) + # order.move_lines.write({'estimated_ready_ship_date': order.estimated_ready_ship_date}) + + @api.onchange('estimated_ready_ship_date') + def _onchange_estimated_ready_ship_date(self): + for record in self: + if (record.estimated_ready_ship_date and record.expected_ready_ship_date): + if(record.estimated_ready_ship_date < record.expected_ready_ship_date): + return { + 'warning': { + 'title': _('Requested date is too soon.'), + 'message': _("The delivery date is sooner than the expected date." + "You may be unable to honor the delivery date.") + } + } + def _prepare_invoice(self): """ Prepare the dict of values to create the new invoice for a sales order. This method may be @@ -573,7 +622,7 @@ class SaleOrder(models.Model): def write(self, vals): res = super(SaleOrder, self).write(vals) - + # self._compute_etrts_date() if 'carrier_id' in vals: for picking in self.picking_ids: if picking.state == 'assigned': @@ -1009,6 +1058,7 @@ class SaleOrder(models.Model): order._set_sppkp_npwp_contact() order.calculate_line_no() order.send_notif_to_salesperson() + order._compute_etrts_date() # order.order_line.get_reserved_from() res = super(SaleOrder, self).action_confirm() @@ -1383,13 +1433,14 @@ class SaleOrder(models.Model): def create(self, vals): # Ensure partner details are updated when a sale order is created order = super(SaleOrder, self).create(vals) + order._compute_etrts_date() # order._update_partner_details() return order def write(self, vals): # Call the super method to handle the write operation res = super(SaleOrder, self).write(vals) - + # self._compute_etrts_date() # Check if the update is coming from a save operation # if any(field in vals for field in ['sppkp', 'npwp', 'email', 'customer_type']): # self._update_partner_details() @@ -1424,4 +1475,6 @@ class SaleOrder(models.Model): raise UserError( "SO tidak dapat ditambahkan produk baru karena SO sudah menjadi sale order.") res = super(SaleOrder, self).write(vals) + if 'order_line' in vals: + self._compute_etrts_date() return res
\ No newline at end of file diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 6967e1a3..f766dc3f 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -1,7 +1,7 @@ from odoo import fields, models, api, _ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools.float_utils import float_is_zero -from datetime import timedelta, datetime +from datetime import timedelta, datetime as waktu from itertools import groupby import pytz, requests, json, requests from dateutil import parser @@ -169,6 +169,33 @@ class StockPicking(models.Model): biteship_id = fields.Char(string="Biteship Respon ID") biteship_tracking_id = fields.Char(string="Biteship Trackcking ID") biteship_waybill_id = fields.Char(string="Biteship Waybill ID") + estimated_ready_ship_date = fields.Datetime(string='ET Ready to Ship', copy=False, store=True, related='sale_id.estimated_ready_ship_date') + countdown_hours = fields.Float(string='Countdown in Hours', compute='_compute_countdown_hours', store=True, default=False) + countdown_ready_to_ship = fields.Char(string='Countdown Ready to Ship', compute='_compute_countdown_ready_to_ship') + + @api.depends('estimated_ready_ship_date', 'state') + def _compute_countdown_hours(self): + for record in self: + if record.state in ('cancel', 'done') or not record.estimated_ready_ship_date: + # Gunakan nilai yang sangat besar sebagai placeholder + record.countdown_hours = 999999 + else: + delta = record.estimated_ready_ship_date - waktu.now() + record.countdown_hours = delta.total_seconds() / 3600 + + @api.depends('estimated_ready_ship_date', 'state') + def _compute_countdown_ready_to_ship(self): + for record in self: + if record.state in ('cancel', 'done'): + record.countdown_ready_to_ship = False + else: + if record.estimated_ready_ship_date: + delta = record.estimated_ready_ship_date - waktu.now() + days = delta.days + hours, remainder = divmod(delta.seconds, 3600) + record.countdown_ready_to_ship = f"{days} days, {hours} hours" + else: + record.countdown_ready_to_ship = False def _compute_lalamove_image_html(self): for record in self: diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index 71748e44..b214dc87 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -31,6 +31,14 @@ <field name="code">model.action_sync_to_solr()</field> </record> + <record id="ir_actions_server_product_sla_generate" model="ir.actions.server"> + <field name="name">Generate Product SLA</field> + <field name="model_id" ref="product.model_product_product"/> + <field name="binding_model_id" ref="product.model_product_product"/> + <field name="state">code</field> + <field name="code">model.generate_product_sla()</field> + </record> + <data noupdate="1"> <record id="cron_variant_solr_flag_solr" model="ir.cron"> <field name="name">Sync Variant To Solr: Solr Flag 2</field> diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 008a04ed..09a71912 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -69,6 +69,7 @@ </field> <field name="tag_ids" position="after"> <field name="eta_date" readonly="1"/> + <field name="estimated_ready_ship_date" /> <field name="flash_sale"/> <field name="margin_after_delivery_purchase"/> <field name="percent_margin_after_delivery_purchase"/> diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 8acba608..ae6ae940 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -7,7 +7,8 @@ <field name="inherit_id" ref="stock.vpicktree"/> <field name="arch" type="xml"> <tree position="attributes"> - <attribute name="default_order">create_date desc</attribute> + <attribute name="default_order">countdown_hours asc</attribute> +<!-- <attribute name="default_order">create_date desc</attribute>--> </tree> <field name="json_popover" position="after"> <field name="date_done" optional="hide"/> @@ -18,6 +19,8 @@ <field name="note" optional="hide"/> <field name="date_reserved" optional="hide"/> <field name="state_reserve" optional="hide"/> + <field name="countdown_hours" optional="hide"/> + <field name="countdown_ready_to_ship" /> </field> <field name="partner_id" position="after"> <field name="purchase_representative_id"/> |
