Odoo18-Base/addons/l10n_in_edi_ewaybill/models/account_move.py

132 lines
6.4 KiB
Python
Raw Permalink Normal View History

2025-01-06 10:57:38 +07:00
# -*- 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()