diff --git a/fusion_accounting_bank_rec/__manifest__.py b/fusion_accounting_bank_rec/__manifest__.py index 38f2886f..1dd147af 100644 --- a/fusion_accounting_bank_rec/__manifest__.py +++ b/fusion_accounting_bank_rec/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Fusion Accounting — Bank Reconciliation', - 'version': '19.0.1.0.8', + 'version': '19.0.1.0.9', 'category': 'Accounting/Accounting', 'sequence': 28, 'summary': 'Native V19 bank reconciliation widget with AI confidence scoring + behavioural learning.', @@ -32,6 +32,14 @@ Built by Nexa Systems Inc. 'security/ir.model.access.csv', 'data/cron.xml', ], + 'assets': { + 'web.assets_backend': [ + 'fusion_accounting_bank_rec/static/src/scss/_variables.scss', + 'fusion_accounting_bank_rec/static/src/scss/bank_reconciliation.scss', + 'fusion_accounting_bank_rec/static/src/scss/ai_suggestion.scss', + 'fusion_accounting_bank_rec/static/src/scss/dark_mode.scss', + ], + }, 'installable': True, 'application': False, 'license': 'OPL-1', diff --git a/fusion_accounting_bank_rec/static/src/scss/_variables.scss b/fusion_accounting_bank_rec/static/src/scss/_variables.scss new file mode 100644 index 00000000..96cf0d68 --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/scss/_variables.scss @@ -0,0 +1,91 @@ +// Fusion bank reconciliation design tokens. +// +// Mirrors Enterprise's color/spacing scale where it makes sense, with +// fusion-specific additions for AI confidence bands and the suggestion +// strip. All values can be overridden in dark_mode.scss. + +// ============================================================ +// Colors — semantic +// ============================================================ +$fusion-color-bg-primary: #ffffff; +$fusion-color-bg-secondary: #f9fafb; +$fusion-color-bg-tertiary: #f3f4f6; +$fusion-color-border: #e5e7eb; +$fusion-color-border-strong: #d1d5db; + +$fusion-color-text-primary: #111827; +$fusion-color-text-secondary: #6b7280; +$fusion-color-text-muted: #9ca3af; +$fusion-color-text-inverse: #ffffff; + +$fusion-color-accent: #3b82f6; // primary brand blue +$fusion-color-accent-hover: #2563eb; +$fusion-color-accent-bg: #eff6ff; + +// ============================================================ +// AI Confidence band colors +// ============================================================ +$fusion-confidence-high: #10b981; // green +$fusion-confidence-high-bg: #ecfdf5; +$fusion-confidence-medium: #f59e0b; // amber +$fusion-confidence-medium-bg: #fffbeb; +$fusion-confidence-low: #ef4444; // red +$fusion-confidence-low-bg: #fef2f2; +$fusion-confidence-none: #9ca3af; // gray +$fusion-confidence-none-bg: #f3f4f6; + +// ============================================================ +// Reconciliation state colors +// ============================================================ +$fusion-state-pending-bg: #fef3c7; // amber-100 +$fusion-state-reconciled-bg: #d1fae5; // emerald-100 +$fusion-state-partial-bg: #fde68a; // amber-200 + +// ============================================================ +// Spacing scale (4px increments) +// ============================================================ +$fusion-space-1: 0.25rem; // 4px +$fusion-space-2: 0.5rem; // 8px +$fusion-space-3: 0.75rem; // 12px +$fusion-space-4: 1rem; // 16px +$fusion-space-5: 1.25rem; // 20px +$fusion-space-6: 1.5rem; // 24px +$fusion-space-8: 2rem; // 32px + +// ============================================================ +// Typography +// ============================================================ +$fusion-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; +$fusion-font-size-xs: 0.75rem; // 12px +$fusion-font-size-sm: 0.875rem; // 14px +$fusion-font-size-base: 1rem; // 16px +$fusion-font-size-lg: 1.125rem; // 18px +$fusion-font-size-xl: 1.25rem; // 20px + +$fusion-font-weight-normal: 400; +$fusion-font-weight-medium: 500; +$fusion-font-weight-semibold: 600; +$fusion-font-weight-bold: 700; + +// ============================================================ +// Borders + radii +// ============================================================ +$fusion-border-radius-sm: 0.25rem; +$fusion-border-radius: 0.375rem; +$fusion-border-radius-md: 0.5rem; +$fusion-border-radius-lg: 0.75rem; + +// ============================================================ +// Shadows +// ============================================================ +$fusion-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); +$fusion-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); +$fusion-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +$fusion-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); + +// ============================================================ +// Animation +// ============================================================ +$fusion-transition-fast: 150ms ease-in-out; +$fusion-transition-base: 200ms ease-in-out; +$fusion-transition-slow: 300ms ease-in-out; diff --git a/fusion_accounting_bank_rec/static/src/scss/ai_suggestion.scss b/fusion_accounting_bank_rec/static/src/scss/ai_suggestion.scss new file mode 100644 index 00000000..e5f78b54 --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/scss/ai_suggestion.scss @@ -0,0 +1,90 @@ +@import "variables"; + +// ============================================================ +// AI Suggestion strip (inline, on each statement line card) +// ============================================================ +.o_fusion_ai_suggestion { + margin-top: $fusion-space-3; + padding: $fusion-space-3; + border-radius: $fusion-border-radius; + border: 1px solid; + display: flex; + align-items: center; + gap: $fusion-space-3; + font-size: $fusion-font-size-sm; + transition: all $fusion-transition-base; + + // Confidence bands — apply via [data-band="..."] attribute + &[data-band="high"] { + background: $fusion-confidence-high-bg; + border-color: $fusion-confidence-high; + + .o_fusion_confidence_value { color: $fusion-confidence-high; } + } + &[data-band="medium"] { + background: $fusion-confidence-medium-bg; + border-color: $fusion-confidence-medium; + + .o_fusion_confidence_value { color: $fusion-confidence-medium; } + } + &[data-band="low"] { + background: $fusion-confidence-low-bg; + border-color: $fusion-confidence-low; + + .o_fusion_confidence_value { color: $fusion-confidence-low; } + } + &[data-band="none"] { + background: $fusion-confidence-none-bg; + border-color: $fusion-confidence-none; + opacity: 0.7; + } + + .o_fusion_confidence_badge { + font-weight: $fusion-font-weight-bold; + font-size: $fusion-font-size-base; + white-space: nowrap; + } + + .o_fusion_suggestion_text { + flex: 1; + color: $fusion-color-text-primary; + + .o_fusion_reasoning { + color: $fusion-color-text-secondary; + font-style: italic; + margin-top: $fusion-space-1; + } + } + + .o_fusion_suggestion_actions { + display: flex; + gap: $fusion-space-2; + } +} + +// ============================================================ +// Alternatives panel (expandable list of other suggestions) +// ============================================================ +.o_fusion_alternatives_panel { + margin-top: $fusion-space-2; + padding: $fusion-space-3; + background: $fusion-color-bg-secondary; + border: 1px solid $fusion-color-border; + border-radius: $fusion-border-radius; + font-size: $fusion-font-size-sm; + + .o_fusion_alternative { + padding: $fusion-space-2 0; + border-bottom: 1px solid $fusion-color-border; + display: flex; + justify-content: space-between; + align-items: center; + + &:last-child { border-bottom: none; } + + .alt_confidence { + font-weight: $fusion-font-weight-medium; + margin-right: $fusion-space-2; + } + } +} diff --git a/fusion_accounting_bank_rec/static/src/scss/bank_reconciliation.scss b/fusion_accounting_bank_rec/static/src/scss/bank_reconciliation.scss new file mode 100644 index 00000000..aeb36ba5 --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/scss/bank_reconciliation.scss @@ -0,0 +1,152 @@ +@import "variables"; + +// ============================================================ +// Bank reconciliation kanban container +// ============================================================ +.o_fusion_bank_rec { + background: $fusion-color-bg-secondary; + min-height: 100vh; + font-family: $fusion-font-family; + color: $fusion-color-text-primary; + + // Header bar with stats + &_header { + background: $fusion-color-bg-primary; + border-bottom: 1px solid $fusion-color-border; + padding: $fusion-space-4 $fusion-space-6; + display: flex; + justify-content: space-between; + align-items: center; + + h1 { + font-size: $fusion-font-size-xl; + font-weight: $fusion-font-weight-semibold; + margin: 0; + } + + .o_fusion_stats { + display: flex; + gap: $fusion-space-6; + font-size: $fusion-font-size-sm; + color: $fusion-color-text-secondary; + + .stat-value { + font-weight: $fusion-font-weight-semibold; + color: $fusion-color-text-primary; + margin-left: $fusion-space-1; + } + } + } + + // Statement line cards (kanban tile) + &_line { + background: $fusion-color-bg-primary; + border: 1px solid $fusion-color-border; + border-radius: $fusion-border-radius-md; + padding: $fusion-space-4; + margin-bottom: $fusion-space-3; + cursor: pointer; + transition: all $fusion-transition-base; + position: relative; + + &:hover { + border-color: $fusion-color-accent; + box-shadow: $fusion-shadow-md; + } + + &.o_fusion_selected { + border-color: $fusion-color-accent; + background: $fusion-color-accent-bg; + } + + &_header { + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: $fusion-space-2; + + .o_fusion_amount { + font-size: $fusion-font-size-lg; + font-weight: $fusion-font-weight-semibold; + + &.negative { + color: $fusion-confidence-low; + } + } + + .o_fusion_date { + font-size: $fusion-font-size-sm; + color: $fusion-color-text-secondary; + } + } + + &_body { + font-size: $fusion-font-size-sm; + color: $fusion-color-text-secondary; + + .o_fusion_partner { + font-weight: $fusion-font-weight-medium; + color: $fusion-color-text-primary; + margin-right: $fusion-space-2; + } + + .o_fusion_memo { + font-style: italic; + color: $fusion-color-text-muted; + } + } + + // Attachment count badge + .o_fusion_attachments_badge { + position: absolute; + top: $fusion-space-2; + right: $fusion-space-2; + background: $fusion-color-bg-tertiary; + border-radius: $fusion-border-radius; + padding: $fusion-space-1 $fusion-space-2; + font-size: $fusion-font-size-xs; + color: $fusion-color-text-secondary; + } + } + + // Detail/edit panel (right side) + &_detail { + background: $fusion-color-bg-primary; + border-left: 1px solid $fusion-color-border; + padding: $fusion-space-6; + + h2 { + font-size: $fusion-font-size-lg; + font-weight: $fusion-font-weight-semibold; + margin: 0 0 $fusion-space-4; + } + } + + // Action buttons + .btn_fusion { + padding: $fusion-space-2 $fusion-space-4; + border-radius: $fusion-border-radius; + font-size: $fusion-font-size-sm; + font-weight: $fusion-font-weight-medium; + border: 1px solid $fusion-color-border; + background: $fusion-color-bg-primary; + color: $fusion-color-text-primary; + cursor: pointer; + transition: all $fusion-transition-fast; + + &:hover { + background: $fusion-color-bg-tertiary; + } + + &.btn_fusion_primary { + background: $fusion-color-accent; + border-color: $fusion-color-accent; + color: $fusion-color-text-inverse; + + &:hover { + background: $fusion-color-accent-hover; + border-color: $fusion-color-accent-hover; + } + } + } +} diff --git a/fusion_accounting_bank_rec/static/src/scss/dark_mode.scss b/fusion_accounting_bank_rec/static/src/scss/dark_mode.scss new file mode 100644 index 00000000..2316281f --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/scss/dark_mode.scss @@ -0,0 +1,64 @@ +@import "variables"; + +// Activated via [data-color-scheme="dark"] on body or any ancestor. +// Mirrors Odoo's standard dark-mode trigger pattern. + +[data-color-scheme="dark"] .o_fusion_bank_rec { + background: #1f2937; + color: #f9fafb; + + &_header, + &_line, + &_detail { + background: #111827; + border-color: #374151; + color: #f9fafb; + } + + &_line { + &:hover { border-color: #60a5fa; } + &.o_fusion_selected { + background: #1e3a8a; + border-color: #60a5fa; + } + + &_header .o_fusion_date, + &_body { color: #d1d5db; } + + .o_fusion_attachments_badge { + background: #374151; + color: #d1d5db; + } + } + + .btn_fusion { + background: #374151; + border-color: #4b5563; + color: #f9fafb; + + &:hover { background: #4b5563; } + + &.btn_fusion_primary { + background: #3b82f6; + border-color: #3b82f6; + + &:hover { + background: #2563eb; + border-color: #2563eb; + } + } + } + + // AI suggestion strip — soften background colors for dark mode + .o_fusion_ai_suggestion { + &[data-band="high"] { background: rgba(16, 185, 129, 0.1); } + &[data-band="medium"] { background: rgba(245, 158, 11, 0.1); } + &[data-band="low"] { background: rgba(239, 68, 68, 0.1); } + &[data-band="none"] { background: rgba(156, 163, 175, 0.1); } + } + + .o_fusion_alternatives_panel { + background: #1f2937; + border-color: #374151; + } +}