from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
import logging
from datetime import datetime
from collections import defaultdict
class GudangService(models.Model):
_name = "gudang.service"
_description = "Gudang Service"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "id asc"
name = fields.Char("Name", readonly=True)
partner_id = fields.Many2one("res.partner", string="Customer", readonly=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, tracking=True)
start_date = fields.Datetime(string="Date Processed", copy=False, tracking=True)
create_date = fields.Datetime(
string="Create Date", copy=False, tracking=True, default=fields.Datetime.now()
)
done_date = fields.Datetime(string="Date Done", copy=False, tracking=True)
gudang_service_lines = fields.One2many(
"gudang.service.line", "gudang_service_id", string="Gudang Service Lines"
)
# unprocessed_date = fields.Char(
# string='Unprocessed Since',
# compute='_compute_unprocessed_date'
# )
remaining_date = fields.Char(
compute="_compute_remaining_date", string="Date Status"
)
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 check_duplicate_docs(self):
for rec in self:
found = self.env["gudang.service"].search(
[
("id", "!=", self.id),
("origin.id", "=", self.origin.id),
("partner_id.id", "=", rec.partner_id.id),
("vendor_id.id", "=", rec.vendor_id.id),
("schedule_date", "=", rec.schedule_date),
(
"gudang_service_lines.product_id.name",
"=",
rec.gudang_service_lines.product_id.name,
),
(
"gudang_service_lines.quantity",
"=",
rec.gudang_service_lines.quantity,
),
]
)
if found:
raise UserError("This Document has duplicate with %s" % found.name)
def _send_logistic_notification(self):
group = self.env.ref(
"indoteknik_custom.group_role_logistic", raise_if_not_found=False
)
if not group:
return
users = group.users
# MD
md = self.env["res.users"].browse([3425, 4801, 1036])
# send to logistic and MD
users = users | md
if not users:
return
# Logistic users to be excluded
excluded_users = [7, 17098, 216, 28, 15710]
for rec in self:
for user in users:
if user.id in excluded_users:
continue
self.env["mail.activity"].create(
{
"res_model_id": self.env["ir.model"]._get_id("gudang.service"),
"res_id": rec.id,
"activity_type_id": self.env.ref(
"mail.mail_activity_data_todo"
).id,
"user_id": user.id,
"summary": "Gudang Service On Progress",
"note": _(
"Ada Jadwal Service Barang di Document %s Jadwal Service 📅 %s"
)
% (rec.name, rec.schedule_date),
# 'date_deadline': fields.Date.today(),
}
)
# kirim ke private message odoo
channel = (
self.env["mail.channel"]
.channel_get([self.env.user.partner_id.id, user.partner_id.id])
.get("id")
)
if not channel:
continue
res = self.env["mail.channel"].browse(channel)
res.with_user(self.env.user.browse(25)).message_post(
body=_(
"Ada Jadwal Service Barang di Document %s Jadwal Service 📅 %s"
)
% (rec.name, rec.schedule_date),
message_type="comment",
subtype_xmlid="mail.mt_comment",
)
@api.model
def cron_notify_onprogress_gudang_service(self):
records = self.search(
[
("state", "in", ["draft", "received_from_customer"]),
]
)
if records:
records._send_logistic_notification()
@api.depends("schedule_date", "create_date")
def _compute_remaining_date(self):
today = fields.Date.today()
for rec in self:
if not rec.schedule_date:
rec.remaining_date = "-"
continue
base_date = rec.create_date.date() if rec.create_date else today
schedule = rec.schedule_date
days = (schedule - base_date).days
if days > 0:
rec.remaining_date = _("In %s days") % days
elif days == 0:
rec.remaining_date = _("Today")
else:
rec.remaining_date = _("Overdue %s days") % abs(days)
def action_submit(self):
self.ensure_one()
self.check_duplicate_docs()
for rec in self:
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:
if rec.state != "received_from_vendor":
raise UserError("Only 'Received From Vendor' state can be set to Done")
rec.activity_ids.unlink()
rec.write(
{"state": "delivered_to_cust", "done_date": fields.Datetime.now()}
)
def action_draft(self):
"""Reset to draft state"""
for rec in self:
rec.cancel_reason = False
if rec.state == "cancel":
rec.write({"state": "draft"})
else:
raise UserError("Only Canceled Record Can Be Reset To Draft")
def action_cancel(self):
for rec in self:
activities = self.env["mail.activity"].search(
[
("res_id", "=", rec.id),
("res_model", "=", "gudang.service"),
]
)
activities.unlink()
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")
rec.start_date = False
rec.done_date = False
rec.state = "cancel"
@api.model
def create(self, vals):
# sequence
if not vals.get("name") or vals["name"] == "New":
vals["name"] = self.env["ir.sequence"].next_by_code("gudang.service")
# partner dari SO
so = self.env["sale.order"].browse(vals["origin"])
vals["partner_id"] = so.partner_id.id
res = super(GudangService, self).create(vals)
res.check_duplicate_docs()
res._send_logistic_notification()
return res
def write(self, vals):
if vals.get("origin"):
so = self.env["sale.order"].browse(vals["origin"])
vals["partner_id"] = so.partner_id.id
vals.check_duplicate_docs()
return super(GudangService, self).write(vals)
@api.onchange("origin")
def _onchange_origin(self):
if not self.origin:
self.gudang_service_lines = [(5, 0, 0)]
return
self.partner_id = self.origin.partner_id
lines = []
for line in self.origin.order_line:
lines.append(
(
0,
0,
{
"product_id": line.product_id.id,
"quantity": line.product_uom_qty,
"origin_so": self.origin.id,
},
)
)
# hapus line lama lalu isi baru
self.gudang_service_lines = [(5, 0, 0)] + lines
class GudangServiceLine(models.Model):
_name = "gudang.service.line"
_inherit = ["mail.thread", "mail.activity.mixin"]
product_id = fields.Many2one("product.product", string="Product")
quantity = fields.Float(string="Quantity")
origin_so = fields.Many2one("sale.order", string="Origin SO")
gudang_service_id = fields.Many2one("gudang.service", string="Gudang Service ID")