diff --git a/modules/automation/__init__.py b/modules/automation/__init__.py index 58b9658..308bd5e 100644 --- a/modules/automation/__init__.py +++ b/modules/automation/__init__.py @@ -1,11 +1,12 @@ -from trytond.pool import Pool -from . import automation,rules,freight_booking,cron #, document - -def register(): - Pool.register( - automation.AutomationDocument, - rules.AutomationRuleSet, - freight_booking.FreightBookingInfo, - cron.Cron, - cron.AutomationCron, - module='automation', type_='model') \ No newline at end of file +from trytond.pool import Pool +from . import automation,rules,freight_booking,booking_report,cron #, document + +def register(): + Pool.register( + automation.AutomationDocument, + rules.AutomationRuleSet, + freight_booking.FreightBookingInfo, + booking_report.FreightBookingShipmentReport, + cron.Cron, + cron.AutomationCron, + module='automation', type_='model') diff --git a/modules/automation/booking_report.py b/modules/automation/booking_report.py new file mode 100644 index 0000000..2475ef2 --- /dev/null +++ b/modules/automation/booking_report.py @@ -0,0 +1,128 @@ +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 + } diff --git a/modules/automation/booking_report.xml b/modules/automation/booking_report.xml new file mode 100644 index 0000000..df857de --- /dev/null +++ b/modules/automation/booking_report.xml @@ -0,0 +1,43 @@ + + + + + freight.booking.shipment.report + tree + freight_booking_shipment_report_tree + + + + Freight Booking Shipment Report + freight.booking.shipment.report + + + + + + + + + freight.booking.shipment.report + + + + + + + freight.booking.shipment.report + + + + + + + + + + diff --git a/modules/automation/tryton.cfg b/modules/automation/tryton.cfg index c8027fb..2af6089 100644 --- a/modules/automation/tryton.cfg +++ b/modules/automation/tryton.cfg @@ -7,4 +7,5 @@ depends: xml: automation.xml freight_booking.xml - cron.xml \ No newline at end of file + booking_report.xml + cron.xml diff --git a/modules/automation/view/freight_booking_shipment_report_tree.xml b/modules/automation/view/freight_booking_shipment_report_tree.xml new file mode 100644 index 0000000..1a4714b --- /dev/null +++ b/modules/automation/view/freight_booking_shipment_report_tree.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/modules/purchase_trade/view/coffee_sample_form.xml b/modules/purchase_trade/view/coffee_sample_form.xml index 314da17..f8ed2bb 100644 --- a/modules/purchase_trade/view/coffee_sample_form.xml +++ b/modules/purchase_trade/view/coffee_sample_form.xml @@ -1,7 +1,6 @@
- + - +