summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/gudang_service.py
diff options
context:
space:
mode:
Diffstat (limited to 'indoteknik_custom/models/gudang_service.py')
-rw-r--r--indoteknik_custom/models/gudang_service.py273
1 files changed, 273 insertions, 0 deletions
diff --git a/indoteknik_custom/models/gudang_service.py b/indoteknik_custom/models/gudang_service.py
new file mode 100644
index 00000000..d699ccf4
--- /dev/null
+++ b/indoteknik_custom/models/gudang_service.py
@@ -0,0 +1,273 @@
+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 <b>%s</b> Jadwal Service 📅 <b>%s</b>"
+ )
+ % (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 <b>%s</b> Jadwal Service 📅 <b>%s</b>"
+ )
+ % (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")