summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2026-02-14 11:16:39 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2026-02-14 11:16:39 +0700
commit17e9e2303ac37e77676326608a71d68a2dc35197 (patch)
tree450855b8102aff95866e093b72138b6f20417a9f
parent30e7aae41d50528a4e61e6f55f38e3dd647e41c6 (diff)
parent55a8c1e5b204bd19733f3197b253293bc00fdf32 (diff)
Merge branch 'gudang-service' of https://bitbucket.org/altafixco/indoteknik-addons into gudang-service
-rwxr-xr-xindoteknik_custom/models/__init__.py2
-rw-r--r--indoteknik_custom/models/gudang_service.py108
-rw-r--r--indoteknik_custom/models/tukar_guling.py116
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv2
-rw-r--r--indoteknik_custom/views/gudang_service.xml23
5 files changed, 103 insertions, 148 deletions
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index 3b3dcd9d..4e5c3d3b 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -166,4 +166,4 @@ from . import domain_apo
from . import uom_uom
from . import commission_internal
from . import gudang_service
-from . import update_depreciation_move_wizard \ No newline at end of file
+from . import update_depreciation_move_wizard
diff --git a/indoteknik_custom/models/gudang_service.py b/indoteknik_custom/models/gudang_service.py
index 1056c4c8..4900113f 100644
--- a/indoteknik_custom/models/gudang_service.py
+++ b/indoteknik_custom/models/gudang_service.py
@@ -13,8 +13,8 @@ class GudangService(models.Model):
name = fields.Char('Name', readonly=True)
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True)
- vendor_id = fields.Many2one('res.partner', string='Vendor', readonly=True, required=True)
- origin = fields.Many2one('sale.order', string='Origin SO', required=True)
+ vendor_id = fields.Many2one('res.partner', string='Vendor Service', required=True)
+ origin = fields.Many2one('sale.order', string='Origin SO', required=True, domain=[('state', 'in', ['done', 'sale'])])
schedule_date = fields.Date(
string="Schedule Date",
required=True,
@@ -34,9 +34,15 @@ class GudangService(models.Model):
# )
remaining_date = fields.Char(
compute='_compute_remaining_date',
- string='Remaining Date'
+ string='Date Status'
)
- state = fields.Selection([('draft', 'Backlog'), ('onprogress', 'On Progress'),('done', 'Done'), ('cancel', 'Cancel')], default='draft', tracking=True)
+ state = fields.Selection([
+ ('draft', 'Backlog'),
+ ('received_from_cust', 'Received From Customer'),
+ ('sent_to_vendor', 'Sent to Service Vendor'),
+ ('received_from_vendor', 'Received From Service Vendor'),
+ ('delivered_to_cust', 'Delivered to Customer'),
+ ('cancel', 'Cancel')], default='draft', tracking=True)
cancel_reason = fields.Text('Cancel Reason', tracking=True)
def _send_logistic_notification(self):
@@ -82,33 +88,12 @@ class GudangService(models.Model):
@api.model
def cron_notify_onprogress_gudang_service(self):
records = self.search([
- ('state', '=', 'draft')
+ ('state', 'in', ['draft', 'received_from_customer']),
])
if records:
records._send_logistic_notification()
- # @api.depends('schedule_date', 'start_date', 'state')
- # def _compute_unprocessed_date(self):
- # today = fields.Date.today()
-
- # for rec in self:
- # if not rec.schedule_date or rec.state == 'cancel':
- # rec.unprocessed_date = "-"
- # continue
-
- # schedule = rec.schedule_date
-
- # # BELUM DIPROSES
- # if not rec.start_date:
- # days = (today - schedule).days
-
- # # SUDAH DIPROSES
- # else:
- # days = (rec.start_date.date() - schedule).days
-
- # rec.unprocessed_date = _("Unprocessed %s days") % max(days, 0)
-
@api.depends('schedule_date', 'create_date')
def _compute_remaining_date(self):
today = fields.Date.today()
@@ -133,21 +118,28 @@ class GudangService(models.Model):
def action_submit(self):
for rec in self:
- rec.state = 'onprogress'
- rec.start_date = fields.Datetime.now()
- # rec.date = fields.Datetime.now()
+ if rec.state == 'draft':
+ rec.state = 'received_from_cust'
+ elif rec.state == 'received_from_cust':
+ rec.state = 'sent_to_vendor'
+ rec.start_date = fields.Datetime.now()
+ elif rec.state == 'sent_to_vendor':
+ rec.state = 'received_from_vendor'
def action_done(self):
- for rec in self:
- activities = self.env['mail.activity'].search([
- ('res_id', '=', rec.id),
- ('res_model', '=', 'gudang.service'),
- ('state', '=', 'done')
- ])
- activities.unlink()
- rec.state = 'done'
- if not rec.done_date:
- rec.done_date = fields.Datetime.now()
+ if self.state != 'received_from_vendor':
+ raise UserError("Only 'Received From Vendor' state can be set to Done")
+ else:
+ for rec in self:
+ activities = self.env['mail.activity'].search([
+ ('res_id', '=', rec.id),
+ ('res_model', '=', 'gudang.service'),
+ ('state', '=', 'delivered_to_cust'),
+ ])
+ activities.unlink()
+ rec.state = 'delivered_to_cust'
+ if not rec.done_date:
+ rec.done_date = fields.Datetime.now()
def action_draft(self):
"""Reset to draft state"""
@@ -165,7 +157,7 @@ class GudangService(models.Model):
('res_model', '=', 'gudang.service'),
])
activities.unlink()
- if rec.state == 'done':
+ if rec.state == 'delivered_to_cust':
raise UserError("You cannot cancel a done record")
if not rec.cancel_reason:
raise UserError("Cancel Reason must be filled")
@@ -183,42 +175,6 @@ class GudangService(models.Model):
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)
res._send_logistic_notification()
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index 03af984f..619e7c99 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -62,7 +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
+ # ('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'),
@@ -933,64 +933,64 @@ class TukarGuling(models.Model):
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")
+ # 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")
+ # 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
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index 9859b127..50e2b382 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -217,4 +217,4 @@ access_sj_tele,access.sj.tele,model_sj_tele,base.group_system,1,1,1,1
access_stock_picking_sj_document,stock.picking.sj.document,model_stock_picking_sj_document,base.group_user,1,1,1,1
access_gudang_service,gudang.service,model_gudang_service,base.group_user,1,1,1,1
access_gudang_service_line,gudang.service.line,model_gudang_service_line,base.group_user,1,1,1,1
-access_update_depreciation_move_wizard,access.update.depreciation.move.wizard,model_update_depreciation_move_wizard,,1,1,1,1 \ No newline at end of file
+access_update_depreciation_move_wizard,access.update.depreciation.move.wizard,model_update_depreciation_move_wizard,,1,1,1,1
diff --git a/indoteknik_custom/views/gudang_service.xml b/indoteknik_custom/views/gudang_service.xml
index 9a8382d3..e5cc94c4 100644
--- a/indoteknik_custom/views/gudang_service.xml
+++ b/indoteknik_custom/views/gudang_service.xml
@@ -6,10 +6,8 @@
<field name="name">gudang.serivice.tree</field>
<field name="model">gudang.service</field>
<field name="arch" type="xml">
- <tree string="Monitoring Barang Service"
- decoration-danger="state == 'draft'" decoration-warning="state == 'onprogress'"
- decoration-success="state == 'done'" decoration-muted="state == 'cancel'"
- >
+ <tree string="Monitoring Barang Service" decoration-danger="state in ('draft', 'received_from_cust')" decoration-warning="state in ('sent_to_vendor', 'received_from_vendor')"
+ decoration-success="state == 'delivered_to_cust'" decoration-muted="state == 'cancel'" >
<field name="name"/>
<field name="partner_id"/>
<field name="vendor_id"/>
@@ -17,8 +15,8 @@
<field name="schedule_date"/>
<field name="start_date" optional="hide"/>
<field name="remaining_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="state" widget="badge" decoration-danger="state in ('draft', 'received_from_cust')" decoration-warning="state in ('sent_to_vendor', 'received_from_vendor')"
+ decoration-success="state == 'delivered_to_cust'" decoration-muted="state == 'cancel'" />
<field name="cancel_reason" optional="hide"/>
<field name="create_date" optional="hide"/>
</tree>
@@ -33,16 +31,16 @@
<header>
<button name="action_submit" string="Proceed" type="object"
class="btn-primary"
- attrs="{'invisible': [('state', 'in', ['cancel', 'done', 'onprogress'])]}"/>
+ attrs="{'invisible': [('state', 'in', ['cancel', 'done', 'received_from_vendor', 'delivered_to_cust'])]}"/>
<button name="action_done" string="Set Done" type="object"
class="btn-primary"
- attrs="{'invisible': [('state', 'not in', ['onprogress'])]}"/>
+ attrs="{'invisible': [('state', 'not in', ['received_from_vendor'])]}"/>
<button name="action_cancel" string="Cancel" type="object"
class="btn-secondary"
- attrs="{'invisible': [('state', 'in', ['cancel', 'done', 'draft'])]}"/>
+ attrs="{'invisible': [('state', 'in', ['cancel', 'delivered_to_cust'])]}"/>
<button name="action_draft" string="Set to Backlog" type="object"
class="btn-secondary"
- attrs="{'invisible': [('state', 'in', ['draft', 'done', 'onprogress'])]}"/>
+ attrs="{'invisible': [('state', 'not in', ['cancel'])]}"/>
<field name="state" widget="statusbar" readonly="1"/>
</header>
<sheet>
@@ -58,16 +56,17 @@
<field name="remaining_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'])]}"/>
+ <field name="done_date" attrs="{'invisible': [('state', 'not in', ['delivered_to_cust'])]}"/>
<field name="create_uid"/>
<field name="cancel_reason"
- attrs="{'invisible': [('state', 'in', ['done', 'draft'])]}"/>
+ attrs="{'invisible': [('state', 'in', ['delivered_to_cust', 'draft'])]}"/>
</group>
<notebook>
<page string="Product Lines" name="product_lines">
<field name="gudang_service_lines">
<tree string="Product Lines" editable="top" create="0" delete="1">
<field name="product_id"/>
+ <field name="quantity"/>
</tree>
</field>
</page>