132 lines
6.4 KiB
Python
132 lines
6.4 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
import json
|
||
|
from odoo import fields, models, api, _
|
||
|
from odoo.exceptions import UserError
|
||
|
|
||
|
|
||
|
class AccountMove(models.Model):
|
||
|
_inherit = "account.move"
|
||
|
|
||
|
# Transaction Details
|
||
|
l10n_in_type_id = fields.Many2one("l10n.in.ewaybill.type", "E-waybill Document Type", tracking=True)
|
||
|
|
||
|
# transportation details
|
||
|
l10n_in_distance = fields.Integer("Distance", tracking=True)
|
||
|
l10n_in_mode = fields.Selection([
|
||
|
("0", "Managed by Transporter"),
|
||
|
("1", "Road"),
|
||
|
("2", "Rail"),
|
||
|
("3", "Air"),
|
||
|
("4", "Ship")],
|
||
|
string="Transportation Mode", copy=False, tracking=True)
|
||
|
|
||
|
# Vehicle Number and Type required when transportation mode is By Road.
|
||
|
l10n_in_vehicle_no = fields.Char("Vehicle Number", copy=False, tracking=True)
|
||
|
l10n_in_vehicle_type = fields.Selection([
|
||
|
("R", "Regular"),
|
||
|
("O", "Over Dimensional Cargo")],
|
||
|
string="Vehicle Type", copy=False, tracking=True)
|
||
|
|
||
|
# Document number and date required in case of transportation mode is Rail, Air or Ship.
|
||
|
l10n_in_transportation_doc_no = fields.Char(
|
||
|
string="E-waybill Document Number",
|
||
|
help="""Transport document number. If it is more than 15 chars, last 15 chars may be entered""",
|
||
|
copy=False, tracking=True)
|
||
|
l10n_in_transportation_doc_date = fields.Date(
|
||
|
string="Document Date",
|
||
|
help="Date on the transporter document",
|
||
|
copy=False,
|
||
|
tracking=True)
|
||
|
|
||
|
# transporter id required when transportation done by other party.
|
||
|
l10n_in_transporter_id = fields.Many2one("res.partner", "Transporter", copy=False, tracking=True)
|
||
|
# show and hide fields base on this
|
||
|
l10n_in_edi_ewaybill_direct_api = fields.Boolean(string="E-waybill(IN) direct API", compute="_compute_l10n_in_edi_ewaybill_direct")
|
||
|
l10n_in_edi_ewaybill_show_send_button = fields.Boolean(string="Show Send E-waybill Button", compute="_compute_l10n_in_edi_ewaybill_show_send_button")
|
||
|
|
||
|
@api.depends('state', 'edi_document_ids', 'edi_document_ids.state')
|
||
|
def _compute_l10n_in_edi_ewaybill_show_send_button(self):
|
||
|
edi_format = self.env.ref('l10n_in_edi_ewaybill.edi_in_ewaybill_json_1_03', raise_if_not_found=False)
|
||
|
if not edi_format:
|
||
|
self.l10n_in_edi_ewaybill_show_send_button = False
|
||
|
return
|
||
|
posted_moves = self.filtered(lambda x: x.is_invoice() and x.state == 'posted' and x.country_code == "IN")
|
||
|
for move in posted_moves:
|
||
|
already_sent = move.edi_document_ids.filtered(lambda x: x.edi_format_id == edi_format and x.state in ('sent', 'to_cancel', 'to_send'))
|
||
|
if already_sent:
|
||
|
move.l10n_in_edi_ewaybill_show_send_button = False
|
||
|
else:
|
||
|
move.l10n_in_edi_ewaybill_show_send_button = True
|
||
|
(self - posted_moves).l10n_in_edi_ewaybill_show_send_button = False
|
||
|
|
||
|
@api.depends("l10n_in_gst_treatment")
|
||
|
def _compute_l10n_in_edi_ewaybill_direct(self):
|
||
|
for move in self:
|
||
|
base = self.env["account.edi.format"]._l10n_in_edi_ewaybill_base_irn_or_direct(move)
|
||
|
move.l10n_in_edi_ewaybill_direct_api = base == "direct"
|
||
|
|
||
|
@api.depends("edi_document_ids")
|
||
|
def _compute_l10n_in_edi_show_cancel(self):
|
||
|
super()._compute_l10n_in_edi_show_cancel()
|
||
|
for invoice in self:
|
||
|
if invoice.edi_document_ids.filtered(lambda i: i.edi_format_id.code == "in_ewaybill_1_03" and i.state in ("sent", "to_cancel", "cancelled")):
|
||
|
invoice.l10n_in_edi_show_cancel = True
|
||
|
|
||
|
def _get_l10n_in_edi_ewaybill_response_json(self):
|
||
|
self.ensure_one()
|
||
|
l10n_in_edi = self.edi_document_ids.filtered(lambda i: i.edi_format_id.code == "in_ewaybill_1_03"
|
||
|
and i.state in ("sent", "to_cancel"))
|
||
|
if l10n_in_edi and l10n_in_edi.sudo().attachment_id:
|
||
|
return json.loads(l10n_in_edi.sudo().attachment_id.raw.decode("utf-8"))
|
||
|
else:
|
||
|
return {}
|
||
|
|
||
|
def button_cancel_posted_moves(self):
|
||
|
"""Mark the edi.document related to this move to be canceled."""
|
||
|
reason_and_remarks_not_set = self.env["account.move"]
|
||
|
for move in self:
|
||
|
send_l10n_in_edi_ewaybill = move.edi_document_ids.filtered(lambda doc: doc.edi_format_id.code == "in_ewaybill_1_03")
|
||
|
# check submitted E-waybill does not have reason and remarks
|
||
|
# because it's needed to cancel E-waybill
|
||
|
if send_l10n_in_edi_ewaybill and (not move.l10n_in_edi_cancel_reason or not move.l10n_in_edi_cancel_remarks):
|
||
|
reason_and_remarks_not_set += move
|
||
|
if reason_and_remarks_not_set:
|
||
|
raise UserError(_(
|
||
|
"To cancel E-waybill set cancel reason and remarks at E-waybill tab in: \n%s",
|
||
|
("\n".join(reason_and_remarks_not_set.mapped("name"))),
|
||
|
))
|
||
|
return super().button_cancel_posted_moves()
|
||
|
|
||
|
def l10n_in_edi_ewaybill_send(self):
|
||
|
edi_format = self.env.ref('l10n_in_edi_ewaybill.edi_in_ewaybill_json_1_03')
|
||
|
edi_document_vals_list = []
|
||
|
for move in self:
|
||
|
if move.state != 'posted':
|
||
|
raise UserError(_("You can only create E-waybill from posted invoice"))
|
||
|
errors = edi_format._check_move_configuration(move)
|
||
|
if errors:
|
||
|
raise UserError(_("Invalid invoice configuration:\n\n%s", '\n'.join(errors)))
|
||
|
existing_edi_document = move.edi_document_ids.filtered(lambda x: x.edi_format_id == edi_format)
|
||
|
if existing_edi_document:
|
||
|
if existing_edi_document.state in ('sent', 'to_cancel'):
|
||
|
raise UserError(_("E-waybill is already created"))
|
||
|
existing_edi_document.sudo().write({
|
||
|
'state': 'to_send',
|
||
|
'attachment_id': False,
|
||
|
})
|
||
|
else:
|
||
|
edi_document_vals_list.append({
|
||
|
'edi_format_id': edi_format.id,
|
||
|
'move_id': move.id,
|
||
|
'state': 'to_send',
|
||
|
})
|
||
|
self.env['account.edi.document'].create(edi_document_vals_list)
|
||
|
self.env.ref('account_edi.ir_cron_edi_network')._trigger()
|
||
|
|
||
|
def _can_force_cancel(self):
|
||
|
# OVERRIDE
|
||
|
self.ensure_one()
|
||
|
return any(document.edi_format_id.code == 'in_ewaybill_1_03' and document.state == 'to_cancel' for document in self.edi_document_ids) or super()._can_force_cancel()
|