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")