diff --git a/fusion_plating/fusion_plating/data/fp_landing_data.xml b/fusion_plating/fusion_plating/data/fp_landing_data.xml index e26af20b..f823df61 100644 --- a/fusion_plating/fusion_plating/data/fp_landing_data.xml +++ b/fusion_plating/fusion_plating/data/fp_landing_data.xml @@ -24,15 +24,37 @@ code 1: + return _('Due %s · %dd') % (base, days) + return _('Due %s · %dd late') % (base, -days) + + +def _icons(job, step): + """Compact icon row at the card footer.""" + icons = [] + if step: + if step.requires_signoff and not step.signoff_user_id: + icons.append('🔏') + if step.recipe_node_id \ + and step.recipe_node_id.default_kind == 'bake': + icons.append('🔥') + if job.card_state == 'bake_due': + icons.append('⏰') + if job.card_state == 'no_parts': + icons.append('🚚') + if job.card_state == 'on_hold': + icons.append('💬') + if job.card_state == 'predecessor_locked': + icons.append('🔒') + if job.card_state == 'done': + icons.append('📜') + return icons + + +def _initials_for(user): + if not user or not user.name: + return '' + parts = user.name.strip().split() + if len(parts) == 1: + return parts[0][:2].upper() + return (parts[0][0] + parts[-1][0]).upper() + + +def _sort_key(card): + """Sort within a column: overdue first, then by state priority, + then by due date (earlier = higher priority).""" + return ( + 0 if card['is_overdue'] else 1, + _SORT_PRIORITY.get(card['card_state'], 99), + card['due_date'] or '9999-12-31', + ) diff --git a/fusion_plating/fusion_plating_shopfloor/views/fp_plant_overview_views.xml b/fusion_plating/fusion_plating_shopfloor/views/fp_plant_overview_views.xml index 6a7b0b7a..0d838433 100644 --- a/fusion_plating/fusion_plating_shopfloor/views/fp_plant_overview_views.xml +++ b/fusion_plating/fusion_plating_shopfloor/views/fp_plant_overview_views.xml @@ -28,4 +28,18 @@ fp_process_tree + + + + + + + + + + Shop Floor + fp_plant_kanban + main + +