diff options
| author | Miqdad <ahmadmiqdad27@gmail.com> | 2025-06-17 22:52:39 +0700 |
|---|---|---|
| committer | Miqdad <ahmadmiqdad27@gmail.com> | 2025-06-17 22:52:39 +0700 |
| commit | 34d276fe64a92c4a1c75f6fbf8fa961e84c8afc4 (patch) | |
| tree | f552663a3d3f8b936feec6298176b8e4ec63fd1c | |
| parent | 3a76bd301734621831f291228deaa962c144be5e (diff) | |
<miqdad> push
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 10 | ||||
| -rw-r--r-- | indoteknik_custom/models/tukar_guling.py | 135 | ||||
| -rw-r--r-- | indoteknik_custom/views/tukar_guling.xml | 12 |
3 files changed, 139 insertions, 18 deletions
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index eabef37c..e24bff02 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -26,6 +26,10 @@ biteship_api_key = "biteship_live.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lI class StockPicking(models.Model): _inherit = 'stock.picking' _order = 'final_seq ASC' + tukar_guling_id = fields.Many2one( + 'tukar.guling', + string='Tukar Guling Reference' + ) konfirm_koli_lines = fields.One2many('konfirm.koli', 'picking_id', string='Konfirm Koli', auto_join=True, copy=False) scan_koli_lines = fields.One2many('scan.koli', 'picking_id', string='Scan Koli', auto_join=True, copy=False) @@ -1196,6 +1200,10 @@ class StockPicking(models.Model): def button_validate(self): self.check_invoice_date() + _logger.info("Kode Picking: %s", self.picking_type_id.code) + _logger.info("Group ID: %s", self.group_id) + _logger.info("Group ID ID: %s", self.group_id.id if self.group_id else None) + _logger.info("Is Internal Use: %s", self.is_internal_use) threshold_datetime = waktu(2025, 4, 11, 6, 26) group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])]) @@ -2391,4 +2399,4 @@ class WarningModalWizard(models.TransientModel): def action_continue(self): if self.picking_id: return self.picking_id.with_context(skip_koli_check=True).button_validate() - return {'type': 'ir.actions.act_window_close'} + return {'type': 'ir.actions.act_window_close'}
\ No newline at end of file diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index 5e814459..29670f5c 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -8,6 +8,13 @@ class TukarGuling(models.Model): _order = 'date desc, id desc' _rec_name = 'name' + real_shipping_id = fields.Many2one('res.partner', string='Shipping Address') + + picking_ids = fields.One2many( + 'stock.picking', + 'tukar_guling_id', + string='Transfers' + ) name = fields.Char('Number', required=True, copy=False, readonly=True, default='New') date = fields.Datetime('Date', default=fields.Datetime.now, required=True) out_num = fields.Many2one('stock.picking', 'Nomor BU/Out', @@ -92,6 +99,17 @@ class TukarGuling(models.Model): return new_record + def action_view_picking(self): + self.ensure_one() + action = self.env.ref('stock.action_picking_tree_all').read()[0] + pickings = self.picking_ids + if len(pickings) > 1: + action['domain'] = [('id', 'in', pickings.ids)] + elif pickings: + action['views'] = [(self.env.ref('stock.view_picking_form').id, 'form')] + action['res_id'] = pickings.id + return action + def action_draft(self): """Reset to draft state""" for record in self: @@ -117,29 +135,107 @@ class TukarGuling(models.Model): raise UserError("Return Type harus diisi!") # Cek hak akses berdasarkan state - if self.state == 'approval_sales': - if not self.env.user.has_group('indoteknik_custom.group_role_sales'): - raise UserError("Hanya Sales Manager yang boleh approve tahap ini.") - self.state = 'approval_logistic' - - elif self.state == 'approval_logistic': - if not self.env.user.has_group('indoteknik_custom.group_role_logistic'): - raise UserError("Hanya Logistic Manager yang boleh approve tahap ini.") - self.state = 'approval_finance' - - elif self.state == 'approval_finance': - if not self.env.user.has_group('indoteknik_custom.group_role_fat'): - raise UserError("Hanya Finance Manager yang boleh approve tahap ini.") - self.state = 'done' - - else: - raise UserError("Status ini tidak bisa di-approve.") + for rec in self: + if rec.state == 'approval_sales': + if not rec.env.user.has_group('indoteknik_custom.group_role_sales'): + raise UserError("Hanya Sales Manager yang boleh approve tahap ini.") + rec.state = 'approval_logistic' + + elif rec.state == 'approval_logistic': + if not rec.env.user.has_group('indoteknik_custom.group_role_logistic'): + raise UserError("Hanya Logistic Manager yang boleh approve tahap ini.") + rec.state = 'approval_finance' + + elif rec.state == 'approval_finance': + if not rec.env.user.has_group('indoteknik_custom.group_role_fat'): + raise UserError("Hanya Finance Manager yang boleh approve tahap ini.") + rec.state = 'done' + rec._create_pickings() + else: + raise UserError("Status ini tidak bisa di-approve.") def action_cancel(self): self.ensure_one() # if self.state == 'done': # raise UserError("Tidak bisa cancel jika sudah done") self.state = 'cancel' + def _create_pickings(self): + if not self.out_num: + raise UserError("BU/Out harus diisi terlebih dahulu.") + + group_id = self.out_num.group_id.id if self.out_num.group_id else False + + Picking = self.env['stock.picking'] + srt_type = self.env['stock.picking.type'].search([ + ('sequence_code', '=', 'SRT') + ], limit=1) + + ort_type = self.env['stock.picking.type'].search([ + ('sequence_code', '=', 'ORT') + ], limit=1) + + # Lokasi + location_dest_id = srt_type.default_location_dest_id.id + location_customer = self.out_num.location_dest_id + + # 1. BU/SRT: retur dari out_num + srt_picking = Picking.create({ + 'partner_id': self.out_num.partner_id.id, + 'picking_type_id': srt_type.id, + 'location_id': location_customer.id, + 'location_dest_id': location_dest_id, + 'origin': f"Retur {self.out_num.name}", + 'tukar_guling_id': self.id, + 'group_id': group_id, + 'move_ids_without_package': [ + (0, 0, { + 'name': line.name or line.product_id.name, + 'product_id': line.product_id.id, + 'product_uom_qty': line.product_uom_qty, + 'product_uom': line.product_uom.id, + 'location_id': location_customer.id, + 'location_dest_id': location_dest_id, + }) for line in self.line_ids + ] + }) + srt_picking.action_confirm() + + # 2. Cari BU/PICK dari SO yang sama + origin_so = self.out_num.origin + if not origin_so: + raise UserError("BU/OUT tidak memiliki origin (SO), tidak bisa cari BU/PICK.") + + pick = Picking.search([ + ('origin', '=', origin_so), + ('picking_type_id.code', '=', 'internal') + ], limit=1) + + if not pick: + raise UserError(f"BU/PICK dengan origin {origin_so} tidak ditemukan.") + + # 3. BU/ORT: retur dari BU/PICK + ort_picking = Picking.create({ + 'partner_id': self.out_num.partner_id.id, + 'picking_type_id': ort_type.id, + 'location_id': location_dest_id, + 'location_dest_id': location_customer.id, + 'origin': f"Retur {pick.name}", + 'tukar_guling_id': self.id, + 'group_id': group_id, + 'move_ids_without_package': [ + (0, 0, { + 'name': line.name or line.product_id.name, + 'product_id': line.product_id.id, + 'product_uom_qty': line.product_uom_qty, + 'product_uom': line.product_uom.id, + 'location_id': location_dest_id, + 'location_dest_id': location_customer.id, + }) for line in self.line_ids + ] + }) + ort_picking.action_confirm() + + class TukarGulingPO(models.Model): _name = 'tukar.guling.po' _description = 'Tukar Guling PO' @@ -322,3 +418,8 @@ class TukarGulingLinePO(models.Model): if self.product_id: self.name = self.product_id.display_name self.product_uom = self.product_id.uom_id + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + origin_tukar_guling_id = fields.Many2one('tukar.guling', string='Tukar Guling Ref')
\ No newline at end of file diff --git a/indoteknik_custom/views/tukar_guling.xml b/indoteknik_custom/views/tukar_guling.xml index e008d2a1..a3b7ce23 100644 --- a/indoteknik_custom/views/tukar_guling.xml +++ b/indoteknik_custom/views/tukar_guling.xml @@ -70,6 +70,15 @@ statusbar_visible="draft,approval_sales,approval_logistic,approval_finance,done"/> </header> <sheet> + <div class="oe_button_box"> + <button name="action_view_picking" + type="object" + class="oe_stat_button" + icon="fa-truck" + attrs="{'invisible': [('picking_ids', '=', False)]}"> + <field name="picking_ids" widget="statinfo" string="Delivery"/> + </button> + </div> <div class="oe_title"> <h1> <field name="name" readonly="1" class="oe_inline"/> @@ -80,6 +89,9 @@ <group> <field name="date" string="Date" readonly="1"/> <field name="return_type"/> + <field name="origin" readonly="1"/> + <field name="ort_num" readonly="1"/> + <field name="srt_num" readonly="1"/> <field name="out_num" string="BU/Out" attrs="{ 'invisible': [('return_type', 'not in', ['revisi_so', 'credit_memo', 'tukar_guling'])], |
