fleet_work_order_passanger/models/fleet_work_order_passanger.py
# Copyright 2018 OpenSynergy Indonesia
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# pylint: disable=W0622
import base64
from datetime import datetime
import openerp.addons.product.product as t_product
import pytz
from openerp import api, fields, models
from openerp.exceptions import ValidationError, Warning as UserError
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.translate import _
# TODO: Remove me to other module
def isodd(x):
return bool(x % 2)
class FleetWorkOrderPassanger(models.Model):
_name = "fleet.work_order_passanger"
_inherit = ["mail.thread"]
_description = "Fleet Work Order Passanger"
@api.multi
@api.depends("work_order_id")
def _compute_allowed_type_ids(self):
for passanger in self:
passanger.allowed_type_ids = False
if (
passanger.work_order_id
and passanger.work_order_id.type_id
and passanger.work_order_id.type_id.passanger_type_ids
):
result = []
for pass_type in passanger.work_order_id.type_id.passanger_type_ids:
result.append(pass_type.passanger_type_id.id)
passanger.allowed_type_ids = [(6, 0, result)]
work_order_id = fields.Many2one(
string="# Work Order",
comodel_name="fleet.work.order",
required=True,
readonly=True,
states={
"draft": [
("readonly", False),
],
},
)
work_order_type_id = fields.Many2one(
string="Work Order Type",
comodel_name="fleet.work.order.type",
related="work_order_id.type_id",
store=True,
readonly=True,
)
vehicle_id = fields.Many2one(
string="Vehicle",
comodel_name="fleet.vehicle",
related="work_order_id.vehicle_id",
)
name = fields.Char(
string="# Passanger",
default="/",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
required=True,
)
partner_id = fields.Many2one(
string="Passanger",
comodel_name="res.partner",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
required=False,
track_visibility="onchange",
)
start_location_id = fields.Many2one(
string="Start Location",
comodel_name="res.partner",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
track_visibility="onchange",
)
end_location_id = fields.Many2one(
string="End Location",
comodel_name="res.partner",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
track_visibility="onchange",
)
type_id = fields.Many2one(
string="Passanger Type",
comodel_name="fleet.work_order_passanger_type",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
required=True,
track_visibility="onchange",
)
allowed_type_ids = fields.Many2many(
string="Allowed Type",
comodel_name="fleet.work_order_passanger_type",
compute="_compute_allowed_type_ids",
store=False,
)
seat_id = fields.Many2one(
string="Seat",
comodel_name="fleet.vehicle.seat",
readonly=True,
states={
"draft": [
("readonly", False),
],
},
track_visibility="onchange",
)
state = fields.Selection(
string="State",
selection=[
("draft", "Draft"),
("confirm", "Waiting for Validation"),
("valid", "Valid"),
("boarding", "Boarding"),
("disembarking", "Disembarking"),
("cancel", "Cancel"),
],
default="draft",
readonly=True,
required=True,
track_visibility="onchange",
)
barcode_image = fields.Text(
string="Barcode image",
compute="_compute_barcode_image",
)
start_time = fields.Char(string="Start Time", compute="_compute_time")
end_time = fields.Char(string="End Time", compute="_compute_time")
def _get_ean_key(self, code):
sum = 0
for i in range(12):
if isodd(i):
sum += 3 * int(code[i])
else:
sum += int(code[i])
key = (10 - sum % 10) % 10
return str(key)
@api.multi
def _convert_datetime_utc(self, dt):
self.ensure_one()
user = self.env.user
convert_dt = datetime.strptime(dt, DEFAULT_SERVER_DATETIME_FORMAT)
if user.tz:
tz = pytz.timezone(user.tz)
else:
tz = pytz.utc
convert_utc = pytz.utc.localize(convert_dt).astimezone(tz)
format_utc = datetime.strftime(convert_utc, "%H:%M")
return format_utc
@api.multi
@api.depends("work_order_id.date_start", "work_order_id.date_end")
def _compute_time(self):
for data in self:
data.start_time = False
data.end_time = False
if data.work_order_id:
data.start_time = self._convert_datetime_utc(
data.work_order_id.date_start
)
data.end_time = self._convert_datetime_utc(data.work_order_id.date_end)
@api.multi
@api.depends("name")
def _compute_barcode_image(self):
for data in self:
data.barcode_image = None
if data.name != "/":
if t_product.check_ean(data.name):
try:
barcode = self.env["report"].barcode(
"EAN13", data.name, width=300, height=100, humanreadable=0
)
except (ValueError, AttributeError):
raise Warning(_("Cannot convert into barcode."))
barcode_base64 = base64.b64encode(barcode)
data.barcode_image = "data:image/png;base64," + barcode_base64
@api.multi
def action_confirm(self):
for passanger in self:
passanger.write(passanger._prepare_confirm_data())
@api.multi
def action_valid(self):
for passanger in self:
passanger.write(passanger._prepare_valid_data())
@api.multi
def action_boarding(self):
for passanger in self:
passanger.write(passanger._prepare_boarding_data())
@api.multi
def action_disembarking(self):
for passanger in self:
passanger.write(passanger._prepare_disembarking_data())
@api.multi
def action_cancel(self):
for passanger in self:
passanger.write(passanger._prepare_cancel_data())
@api.multi
def action_restart(self):
for passanger in self:
passanger.write(passanger._prepare_restart_data())
@api.multi
def _prepare_confirm_data(self):
self.ensure_one()
return {
"state": "confirm",
}
@api.multi
def _prepare_valid_data(self):
self.ensure_one()
return {
"state": "valid",
}
@api.multi
def _prepare_boarding_data(self):
self.ensure_one()
return {
"state": "boarding",
}
@api.multi
def _prepare_disembarking_data(self):
self.ensure_one()
return {
"state": "disembarking",
}
@api.multi
def _prepare_cancel_data(self):
self.ensure_one()
return {
"state": "cancel",
}
@api.multi
def _prepare_restart_data(self):
self.ensure_one()
return {
"state": "draft",
}
@api.multi
def _prepare_create_data(self, value):
return value
@api.multi
def _get_sequence(self):
self.ensure_one()
result = self.work_order_id._get_passanger_sequence()
return result
@api.multi
def _create_sequence(self):
self.ensure_one()
if self._check_sequence:
name = self.env["ir.sequence"].next_by_id(self._get_sequence().id) or "/"
# TODO: Remove me to different module
name = name + self._get_ean_key(name)
self.write({"name": name})
@api.multi
def _check_sequence(self):
self.ensure_one()
result = False
if self.name == "/":
result = True
return result
@api.model
def create(self, values):
new_values = self._prepare_create_data(values)
passanger = super(FleetWorkOrderPassanger, self).create(new_values)
passanger._create_sequence()
return passanger
@api.multi
def copy(self, default=None):
_super = super(FleetWorkOrderPassanger, self)
res = _super.copy(default)
if default is None:
default = {}
if default:
str_warning = _("You can't copy passanger data")
raise UserError(str_warning)
return res
@api.onchange("work_order_id")
def onchange_start_location_id(self):
self.start_location_id = False
if self.work_order_id:
wo = self.work_order_id
self.start_location_id = wo.start_location_id
@api.onchange("work_order_id")
def onchange_end_location_id(self):
self.end_location_id = False
if self.work_order_id:
wo = self.work_order_id
self.end_location_id = wo.end_location_id
@api.onchange("work_order_id")
def onchange_seat_id(self):
domain = {
"seat_id": [
("id", "=", 0),
],
}
obj_seat = self.env["fleet.vehicle.seat"]
self.seat_id = False
if self.work_order_id and self.work_order_id.vehicle_id:
wo = self.work_order_id
criteria = [
("vehicle_id", "=", wo.vehicle_id.id),
]
seat_ids = obj_seat.search(criteria).ids
domain["seat_id"] = [
("id", "in", seat_ids),
]
return {"domain": domain}
@api.onchange("work_order_id")
def onchange_type_id(self):
self.type_id = False
@api.constrains("partner_id", "work_order_id")
def check_same_partner(self):
obj_passanger = self.env["fleet.work_order_passanger"]
if self.partner_id:
criteria = [
("id", "!=", self.id),
("partner_id", "!=", False),
("partner_id", "=", self.partner_id.id),
]
passanger_count = obj_passanger.search_count(criteria)
if passanger_count > 0:
raise ValidationError(_("Duplicate Partner"))