summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2026-01-30 16:05:57 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2026-01-30 16:05:57 +0700
commit24b33148858c9827ad0b14e716562c377e1644ca (patch)
treeda4cda6cb6169e473cc7c2319657708cfb8741dd
parent23b996c1c9484d735651efaaf999f9d4b10c3328 (diff)
<Miqdad> Initial integration to ccm
-rw-r--r--indoteknik_custom/models/gudang_service.py48
-rw-r--r--indoteknik_custom/models/tukar_guling.py61
-rw-r--r--indoteknik_custom/views/gudang_service.xml10
3 files changed, 103 insertions, 16 deletions
diff --git a/indoteknik_custom/models/gudang_service.py b/indoteknik_custom/models/gudang_service.py
index ce3b2919..1056c4c8 100644
--- a/indoteknik_custom/models/gudang_service.py
+++ b/indoteknik_custom/models/gudang_service.py
@@ -20,7 +20,6 @@ class GudangService(models.Model):
required=True,
tracking=True
)
-
start_date = fields.Datetime(
string="Date Processed",
copy=False,
@@ -54,6 +53,7 @@ class GudangService(models.Model):
if not users:
return
+ # Logistic users to be excluded
excluded_users = [7, 17098, 216, 28, 15710]
for rec in self:
@@ -175,16 +175,52 @@ class GudangService(models.Model):
@api.model
def create(self, vals):
- # Send notification
+ # sequence
if not vals.get('name') or vals['name'] == 'New':
vals['name'] = self.env['ir.sequence'].next_by_code('gudang.service')
- if vals.get('origin') and not vals.get('partner_id'):
- so = self.env['sale.order'].browse(vals['origin'])
- vals['partner_id'] = so.partner_id.id
+ # partner dari SO
+ so = self.env['sale.order'].browse(vals['origin'])
+ vals['partner_id'] = so.partner_id.id
+
+ # 1️⃣ Cari BU/OUT dari SO
+ picking = self.env['stock.picking'].search([
+ ('origin', '=', so.name),
+ ('picking_type_id', '=', 29), # BU/OUT
+ ('state', '=', 'done'),
+ ], limit=1)
+
+ if not picking:
+ raise UserError("BU/OUT (done) tidak ditemukan untuk SO ini.")
+
+ # 2️⃣ Validasi product service ada di picking
+ picking_products = picking.move_lines.mapped('product_id')
+ service_lines = vals.get('gudang_service_lines', [])
+
+ tg_lines = []
+ for line in service_lines:
+ product = self.env['product.product'].browse(line[2]['product_id'])
+ if product not in picking_products:
+ raise UserError(
+ f"Produk {product.display_name} tidak ada di BU/OUT {picking.name}"
+ )
+
+ tg_lines.append((0, 0, {
+ 'product_id': product.id,
+ 'quantity': line[2]['quantity'],
+ }))
+
+ # 3️⃣ Create Tukar Guling
+ self.env['tukar.guling'].create({
+ 'origin_so': so.id,
+ 'operation_type': 'service',
+ 'partner_id': so.partner_id.id,
+ 'operations': picking.id,
+ 'line_ids': tg_lines,
+ })
res = super(GudangService, self).create(vals)
- # Send notification
+
res._send_logistic_notification()
return res
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index 682c478a..03af984f 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -62,6 +62,7 @@ class TukarGuling(models.Model):
notes = fields.Text('Notes')
return_type = fields.Selection(String='Return Type', selection=[
('tukar_guling', 'Tukar Guling'), # -> barang yang sama
+ ('service', 'Service'), # -> barang yang sama
('retur_so', 'Retur SO')], required=True, tracking=3, help='Retur SO (ORT-SRT),\n Tukar Guling (ORT-SRT-PICK-OUT)')
state = fields.Selection(string='Status', selection=[
('draft', 'Draft'),
@@ -931,6 +932,66 @@ class TukarGuling(models.Model):
_logger.info(f"✅ BU/PICK Baru dari ORT created: {new_pick.name}")
record.message_post(
body=f"📦 <b>{new_pick.name}</b> created by <b>{self.env.user.name}</b> (state: <b>{new_pick.state}</b>)")
+
+ if record.return_type == 'service':
+ GUDANG_SERVICE_LOCATION_ID = 98
+ # From STOCK to OUTPUT
+ done_service = self.env['stock.picking'].create({
+ 'group_id': bu_out.group_id.id,
+ 'tukar_guling_id': record.id,
+ 'sale_order': record.origin,
+ 'note': record.notes,
+ 'picking_type_id': 32,
+ 'location_id': GUDANG_SERVICE_LOCATION_ID,
+ 'location_dest_id': BU_STOCK_LOCATION_ID,
+ 'partner_id': bu_out.partner_id.id,
+ 'move_ids_without_package': [(0, 0, {
+ 'product_id': line.product_id.id,
+ 'product_uom_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id,
+ 'name': line.product_id.display_name,
+ 'location_id': GUDANG_SERVICE_LOCATION_ID,
+ 'location_dest_id': BU_STOCK_LOCATION_ID,
+ }) for line in record.line_ids],
+ })
+ if done_service:
+ done_service.action_confirm()
+ done_service.action_assign()
+ else:
+ raise UserError("Gagal membuat picking service")
+
+ service_to_output = self.env['stock.picking'].create({
+ 'group_id': bu_out.group_id.id,
+ 'tukar_guling_id': record.id,
+ 'sale_order': record.origin,
+ 'note': record.notes,
+ 'picking_type_id': 32,
+ 'location_id': BU_STOCK_LOCATION_ID,
+ 'location_dest_id': BU_OUTPUT_LOCATION_ID,
+ 'partner_id': bu_out.partner_id.id,
+ 'move_lines': [(0, 0, {
+ 'product_id': line.product_id.id,
+ 'product_uom_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id,
+ 'name': line.product_id.display_name,
+ 'location_id':BU_STOCK_LOCATION_ID,
+ 'location_dest_id': BU_STOCK_LOCATION_ID,
+ }) for line in record.line_ids],
+ 'move_ids_without_package': [(0, 0, {
+ 'product_id': line.product_id.id,
+ 'product_uom_qty': line.product_uom_qty,
+ 'product_uom': line.product_uom.id,
+ 'name': line.product_id.display_name,
+ 'location_id': BU_STOCK_LOCATION_ID,
+ 'location_dest_id': BU_OUTPUT_LOCATION_ID,
+ }) for line in record.line_ids],
+ })
+ if service_to_output:
+ service_to_output.action_confirm()
+ service_to_output.action_assign()
+ else:
+ raise UserError("Gagal membuat picking service")
+
# BU/OUT Baru dari SRT
if srt_picking:
diff --git a/indoteknik_custom/views/gudang_service.xml b/indoteknik_custom/views/gudang_service.xml
index e06e9e7e..9a8382d3 100644
--- a/indoteknik_custom/views/gudang_service.xml
+++ b/indoteknik_custom/views/gudang_service.xml
@@ -6,11 +6,6 @@
<field name="name">gudang.serivice.tree</field>
<field name="model">gudang.service</field>
<field name="arch" type="xml">
- <!-- <tree string="Monitoring Gudang Service"
- decoration-warning="state == 'draft'" decoration-danger="state == 'onprogress'"
- decoration-success="state == 'done'" decoration-muted="state == 'cancel'"
- decoration-bf="remaining_date &gt; 7"
- > -->
<tree string="Monitoring Barang Service"
decoration-danger="state == 'draft'" decoration-warning="state == 'onprogress'"
decoration-success="state == 'done'" decoration-muted="state == 'cancel'"
@@ -22,12 +17,10 @@
<field name="schedule_date"/>
<field name="start_date" optional="hide"/>
<field name="remaining_date"/>
- <!-- <field name="unprocessed_date"/> -->
<field name="state" widget="badge" decoration-danger="state in ('draft')" decoration-warning="state == 'onprogress'"
decoration-success="state == 'done'" decoration-muted="state == 'cancel'" />
<field name="cancel_reason" optional="hide"/>
<field name="create_date" optional="hide"/>
- <!-- <field name="picking_id"/> -->
</tree>
</field>
</record>
@@ -63,7 +56,6 @@
<field name="partner_id"/>
<field name="vendor_id"/>
<field name="remaining_date"/>
- <!-- <field name="unprocessed_date"/> -->
<field name="schedule_date" attrs="{'readonly': [('state', 'not in', ['draft'])]}"/>
<field name="start_date" readonly="1"/>
<field name="done_date" attrs="{'invisible': [('state', 'not in', ['done'])]}"/>
@@ -76,8 +68,6 @@
<field name="gudang_service_lines">
<tree string="Product Lines" editable="top" create="0" delete="1">
<field name="product_id"/>
- <!-- <field name="quantity"/> -->
- <!-- <field name="picking_id"/> -->
</tree>
</field>
</page>