129 lines
4.2 KiB
Python
129 lines
4.2 KiB
Python
import json
|
|
|
|
from sql import Literal, Null
|
|
from sql.functions import CurrentTimestamp
|
|
|
|
from trytond.model import ModelSQL, ModelView, fields
|
|
from trytond.pool import Pool
|
|
|
|
|
|
class FreightBookingShipmentReport(ModelSQL, ModelView):
|
|
"Freight Booking Shipment Report"
|
|
__name__ = 'freight.booking.shipment.report'
|
|
|
|
automation_document = fields.Many2One(
|
|
'automation.document', "Automation Document")
|
|
bl_number = fields.Function(fields.Char("BL Number"), 'get_bl_number')
|
|
shipment = fields.Function(fields.Many2One(
|
|
'stock.shipment.in', "Shipment"), 'get_shipment')
|
|
status = fields.Function(fields.Selection([
|
|
('found', "Found"),
|
|
('error', "Error"),
|
|
], "Status"), 'get_status')
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls._order = [
|
|
('id', 'DESC'),
|
|
]
|
|
|
|
@classmethod
|
|
def table_query(cls):
|
|
AutomationDocument = Pool().get('automation.document')
|
|
document = AutomationDocument.__table__()
|
|
|
|
return document.select(
|
|
Literal(None).as_('create_uid'),
|
|
CurrentTimestamp().as_('create_date'),
|
|
Literal(None).as_('write_uid'),
|
|
Literal(None).as_('write_date'),
|
|
document.id.as_('id'),
|
|
document.id.as_('automation_document'),
|
|
where=(
|
|
(document.type == 'weight_report')
|
|
& (document.metadata_json != Null)))
|
|
|
|
@classmethod
|
|
def _extract_bl_number(cls, metadata_json):
|
|
if not metadata_json:
|
|
return None
|
|
try:
|
|
metadata = json.loads(str(metadata_json))
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
def find_value(value):
|
|
if isinstance(value, dict):
|
|
for key in (
|
|
'bl_no', 'bl_number', 'bl', 'BL_Number',
|
|
'BL number', 'B/L No'):
|
|
bl_number = value.get(key)
|
|
if bl_number:
|
|
return str(bl_number).strip()
|
|
for item in value.values():
|
|
bl_number = find_value(item)
|
|
if bl_number:
|
|
return bl_number
|
|
elif isinstance(value, list):
|
|
for item in value:
|
|
bl_number = find_value(item)
|
|
if bl_number:
|
|
return bl_number
|
|
return None
|
|
|
|
return find_value(metadata)
|
|
|
|
@classmethod
|
|
def _get_report_data(cls, reports):
|
|
ShipmentIn = Pool().get('stock.shipment.in')
|
|
bl_numbers = {}
|
|
|
|
for report in reports:
|
|
document = report.automation_document
|
|
bl_number = cls._extract_bl_number(
|
|
document.metadata_json if document else None)
|
|
bl_numbers[report.id] = bl_number
|
|
|
|
shipments_by_bl = {}
|
|
for bl_number in {b for b in bl_numbers.values() if b}:
|
|
shipments = ShipmentIn.search([
|
|
('bl_number', '=', bl_number),
|
|
], limit=1)
|
|
if not shipments:
|
|
shipments = ShipmentIn.search([
|
|
('bl_number', 'ilike', bl_number),
|
|
], limit=1)
|
|
shipments_by_bl[bl_number] = shipments[0] if shipments else None
|
|
|
|
return bl_numbers, shipments_by_bl
|
|
|
|
@classmethod
|
|
def get_bl_number(cls, reports, name):
|
|
bl_numbers, _ = cls._get_report_data(reports)
|
|
return bl_numbers
|
|
|
|
@classmethod
|
|
def get_shipment(cls, reports, name):
|
|
bl_numbers, shipments_by_bl = cls._get_report_data(reports)
|
|
return {
|
|
report.id: (
|
|
shipments_by_bl[bl_numbers[report.id]].id
|
|
if bl_numbers[report.id]
|
|
and shipments_by_bl.get(bl_numbers[report.id])
|
|
else None)
|
|
for report in reports
|
|
}
|
|
|
|
@classmethod
|
|
def get_status(cls, reports, name):
|
|
bl_numbers, shipments_by_bl = cls._get_report_data(reports)
|
|
return {
|
|
report.id: (
|
|
'found'
|
|
if bl_numbers[report.id]
|
|
and shipments_by_bl.get(bl_numbers[report.id])
|
|
else 'error')
|
|
for report in reports
|
|
}
|