Compare commits

..

89 Commits

Author SHA1 Message Date
98c96018d6 Fix SFTP makedirs error with trailing slashes
- Normalize remote paths by removing trailing slashes
- Improve error handling for directory creation
- Fix OSError handling (errno not reliably set in SFTP)
- Prevents duplicate directory creation attempts
2026-01-11 20:43:25 +01:00
b2f7a5edbf added auto_backup tool 2026-01-11 20:21:24 +01:00
d6c2986ebf Verbessere Image Generator: Fixierter Crop-Rahmen, optimierte Vorschau-Skalierung
- Crop-Rahmen ist fixiert (nicht verschiebbar/skalierbar), nur Bild bewegbar
- Zuschnitt auf exakt 369×492 Pixel
- Finales Badge im A4-Format (794×1123px / 21×29.7cm)
- Vorschau auf 35% skaliert mit korrektem Platzverbrauch
- Große Bilder passen initial in Container, unbegrenztes Zoomen möglich
- Badge-Template behält alle mm/cm-Maße aus print.html
2026-01-11 18:22:10 +01:00
67184e7e01 fixed template 2026-01-10 19:18:55 +01:00
ee0e6c8b98 added ignored lib 2026-01-10 19:14:25 +01:00
1c9829a7aa feat: open_workshop_employee_imagegenerator - Thekenheld Badge-Generator als Odoo Modul
- OWL Component mit 3-step Wizard (Upload → Crop → Text/Preview)
- Cropper.js für Bildausschnitt (369×492px)
- html2canvas für PNG-Generierung (794×1123px A4)
- Badge-Template mit originalen CSS von Thekenheld
- Speicherung in hr.employee.image_1920
2026-01-10 16:42:39 +01:00
1abeb97afa Cleanup: Remove debug logs, unused backend files, add comprehensive comments
- Removed all console.log debug statements from JavaScript files
- Deleted unnecessary backend models (hr_employee.py, res_users.py, pos_session.py, pos_config.py)
- Added comprehensive German comments explaining the BroadcastChannel architecture
- Updated README with detailed technical documentation about frontend-only approach
- Removed debug info box from customer display template
- Simplified __init__.py files (pure frontend solution)

The module now uses a clean, maintainable frontend-only approach that:
- Patches Chrome component with effect(batched()) for reactive updates
- Sends cashier data via BroadcastChannel (same pattern as order updates)
- Uses hr.employee.public URL format (identical to POS navbar)
- Falls back to company logo when no employee image available
2026-01-10 15:10:51 +01:00
daddb51327 Add POS customer display customization module
- Show current cashier's employee image in customer display sidebar
- Image updates automatically when cashier changes
- Fallback to company logo when no image available or before first order
- Uses BroadcastChannel to sync between POS and customer display
- Full-size image display with correct aspect ratio (object-fit: contain)
2026-01-10 14:49:50 +01:00
5d1faa7b5b POS: Preislistenabhängige Preisanzeige auf Produktkarten
- Fügt reaktive Preisanzeige auf POS-Produktkarten hinzu
- Preis wird basierend auf der Preisliste des aktuellen Kunden berechnet
- Automatische Aktualisierung bei Kundenwechsel/Preislistenänderung
- Unterstützt Maßeinheiten für gewichtsbasierte Produkte
2026-01-09 22:11:01 +01:00
21b0d6305f POS: Rechnungs-Button im Payment Screen entfernt 2026-01-09 21:05:20 +01:00
988421a0c5 POS: Replace internal note button with pricelist button
- Remove internal note button from control buttons
- Add pricelist button directly visible in main view (not only in Actions dialog)
- Shows current pricelist name of the order/partner
- Allows direct access to change pricelist without opening Actions menu
2026-01-09 15:24:26 +01:00
b26e70dbe9 fix: Support multiple file types (PNG, PDF, JPEG) for DokuWiki media uploads
- Make upload_media accept ir.attachment records, IDs, or raw bytes
- Detect file extension from binary content using imghdr
- Build media_id with correct extension (.png, .jpg, .pdf)
- Prevent DokuWiki 'file extension mismatch' error
- Improve temp file cleanup with proper error handling
2026-01-08 17:13:34 +01:00
38d0becfad Fix: Korrigiere Zeitanzeige in POS Sidebar (UTC zu lokaler Zeit) 2026-01-07 19:01:41 +01:00
943d48af58 DokuWiki: Media-Namespace an DokuWiki Best Practice angepasst
- Geändert von :media: Sub-Namespace zu paralleler Struktur :{area}:
- Media-IDs folgen jetzt dem gleichen Muster wie Pages
- Alt: werkstatt:ausstattung:media:{id}.jpg
- Neu: werkstatt:ausstattung:{bereich}:{id}.jpg
- Entspricht DokuWiki-Konvention für parallele Page/Media-Strukturen
- Dokumentation im Docstring aktualisiert
2026-01-07 13:41:50 +01:00
09f28c8070 DokuWiki: Fix partner_ref sync und Template-Cache
- partner_ref zu sync_fields hinzugefügt für automatische Synchronisation
- action_clear_template_cache() Methode hinzugefügt zum manuellen Leeren des Caches
- Template-Cache-Leeren Button im Wiki-Sync Wizard
- Debug-Logging für partner_ref Wert

Fixes: partner_ref wurde nicht automatisch synchronisiert und Template-Änderungen erforderten Server-Neustart
2026-01-07 12:37:34 +01:00
40a5fe8b0f wiki_doku_id wird bei einem Sync Statut reset auch zurück gesetzt 2026-01-07 11:02:22 +01:00
31a40e95d7 Add voucher codes display in POS receipt
- Create ows_order_patch.js to collect voucher codes from orderlines
- Add voucher codes section at end of receipt with large readable format
- Include voucher code, product name, and value for each voucher
- Move partner name logic from receipt_header_patch to order_patch
- Add German labels (GUTSCHEIN-CODES, Wert:)
2026-01-06 14:48:09 +01:00
91209dead4 manifest 2026-01-06 14:12:51 +01:00
9cb6dc8ac5 Add partner name display in POS receipt header
- Patch PosOrder.export_for_printing() to include partner data in headerData
- Update receipt header template to display partner name above tracking number
- Partner name shown only when partner is selected for the order
2026-01-06 14:03:55 +01:00
93385abb0f [ADD] open_workshop_pos: Standard-Kategorie beim POS-Start
- Automatische Auswahl einer konfigurierbaren Standard-Kategorie
- Konfiguration über Kategorie-Name oder ID möglich
- Aktuell auf 'Nutzung' gesetzt
- Vereinfacht die Navigation für häufig genutzte Kategorien
2026-01-06 11:43:56 +01:00
e443f8709d added darker background color for pos 2026-01-06 11:29:16 +01:00
b151894c39 [IMP] open_workshop_pos: Fix Produktsuche und verbessere UI
- Fix: ProductScreen Patch korrigiert - Suchfeld erscheint wieder
  * Verwendung von patch() statt Klassen-Vererbung für korrekte Komponenten-Registrierung
  * Behebt OwlError 'Cannot find OwsPosSidebar'

- Add: Preisanzeige auf Produktkarten
  * Listenpreis wird unter Produktname angezeigt
  * Konsistente Ausrichtung am unteren Rand
  * Produkte mit/ohne Bild haben gleiche Preis-Position

- UX: Warenkorb-Mengenanzeige auf Produktkarten entfernt
  * Ruhigeres, übersichtlicheres Erscheinungsbild
  * Mengen nur noch in Bestellübersicht sichtbar
2026-01-06 11:25:24 +01:00
0c4b58e0a6 Update Open Workshop Dokuwiki Version 2025-12-27 20:37:02 +01:00
e460acddf3 DokuWiki: Reset-Funktion für Wiki-Sync-Status
Neue Funktion im Modul:
- action_reset_wiki_sync_status() in maintenance_equipment.py
- Setzt wiki_synced und wiki_last_sync zurück
- Aufrufbar über Wizard: Wartung → Konfiguration → Wiki-Synchronisation
- Neuer Modus: 'Sync-Status zurücksetzen'

Verwendung:
1. Nach Namespace-Änderungen (ausruestung → ausstattung)
2. Wenn alle Equipment neu synchronisiert werden sollen
3. Bei Wiki-Struktur-Änderungen

Setzt NUR den Status zurück, nicht die wiki_doku_id
(wiki_doku_id kann bei Bedarf manuell zurückgesetzt werden)
2025-12-27 20:25:17 +01:00
a1c6903893 Update Dokuwiki Template in maintenance equipment 2025-12-27 19:54:43 +01:00
72a46e3657 DokuWiki: Übersichtstabelle in 'uebersicht' statt 'start'
- Systemparameter dokuwiki.overview_page_id: werkstatt:ausstattung:uebersicht
- README.md aktualisiert mit neuem Pfad
- 'start' Seite kann nun für andere Zwecke genutzt werden (z.B. Willkommensseite)
2025-12-27 17:01:55 +01:00
641bfb3ade DokuWiki Integration: Neue Namespace-Struktur mit odoo-status
BREAKING CHANGES:
- Namespace-Struktur komplett überarbeitet
- ausruestung → ausstattung (konfigurierbar über dokuwiki.equipment_namespace)
- Neue Struktur: ausstattung:odoo-status/ für Odoo-generierte Status-Seiten
- Odoo erstellt KEINE Benutzer-Seiten mehr in {bereich}/ Namespaces

Neue Systemparameter:
- dokuwiki.equipment_namespace = werkstatt:ausstattung (Basis-Namespace)
- dokuwiki.central_documentation_namespace = werkstatt:ausstattung:odoo-status

Workflow-Änderung:
1. Odoo synchronisiert → erstellt nur start und odoo-status/ Seiten
2. Übersichtstabelle verlinkt auf {bereich}/{equipment_id} → Links sind rot
3. Benutzer klickt roten Link → DokuWiki bietet Seitenerstellung an
4. Benutzer erstellt Seite mit {{page>odoo-status:equipment_id}}

Vorteile:
- Klare Trennung: odoo-status/ (nur Odoo) vs. {bereich}/ (nur Benutzer)
- Keine Überschreibgefahr - Odoo und Benutzer haben getrennte Namespaces
- Benutzer entscheiden selbst ob/wann sie Dokumentation erstellen
- ACL-Schutz: odoo-status/ nur von odoo.odoo schreibbar
2025-12-27 16:56:17 +01:00
a73c0cb299 Integration Plan für automatisierte DokuWiki-Report-Generierung
Roadmap für vollautomatische monatliche PNG-Export-Generierung:
- Graph-Renderer mit Matplotlib/Plotly (alle Metabase-Features möglich)
- Scheduled Action (Cron) für monatliche Ausführung
- DokuWiki XML-RPC Upload Integration
- 5 Diagramm-Typen: Tagesansicht, Jahresvergleich, Trends, Wiederholungstäter
- Aufwand: 5-7 Stunden Implementierung

Vorteil: Vollautomatisch, professionelle Visualisierung mit Beschriftungen,
kein manueller Metabase-Export mehr nötig
2025-12-26 23:47:24 +01:00
4626379d6e Korrektur Ø Nutzer/Tag Berechnung und finale Verbesserungen
- Ø Nutzer/Tag Formel korrigiert: Buchungen/Tage statt Nutzer/Tage
- Jahr/Monat Felder zu DailyStats hinzugefügt für flexible Gruppierung
- Alle 2034 Datensätze neu generiert mit korrekten Werten
- show_measures zu allen Graph-Views hinzugefügt (Odoo-Limitation: funktioniert nicht)

LIMITIERUNG: Weitere Verbesserungen gegenüber Metabase nicht möglich
- Odoo Graph-Views können keine Werte auf Balken anzeigen
- 100% gestapelte Diagramme nicht möglich
- Komplexe Visualisierungen wie Häufigkeitsverteilungen nicht realisierbar
- Für Präsentationen und Export: Metabase bleibt überlegen

Empfehlung: Odoo für operative Arbeit, Metabase für Präsentationen nutzen
2025-12-26 23:40:42 +01:00
9be8f320f7 Tägliche Statistiken mit Drill-Down und Jahresvergleich
- Tägliche Statistiken (DailyStats) implementiert mit 2034 Datensätzen
- Wochenende vs. Wochentag farblich unterschieden in Tagesansicht
- Jahr/Monat Felder für Jahresvergleich hinzugefügt
- Button 'Tagesansicht' in Kanban-Dashboard für Drill-Down zu täglichen Statistiken
- Alle Dashboard-Graphen auf Jahresvergleich umgestellt (Monat × Jahr, nicht gestapelt)
- Jahresvergleich, Ø Nutzer/Tag, Wiederholungstäter, Nutzer pro Monat - alle mit Jahresvergleich
2025-12-26 21:35:22 +01:00
d6a98cfbd0 initiale Version von Open Workshop Report 2025-12-26 19:14:17 +01:00
0135035a54 DokuWiki Integration: Performance-Optimierung und Best Practices
- Connection Caching: Wiederverwendung von DokuWiki-Verbindungen (von 12min auf 20s für 50 Equipment)
- Template Caching: Template nur einmal laden statt pro Equipment
- Dokumentation: Best Practices für erweiterbare DokuWiki-Seitenstruktur (page.txt + page/ ohne start.txt)
- Catlist-Syntax dokumentiert für automatische Unterseiten-Auflistung
2025-12-24 14:13:59 +01:00
f79e126c8c DokuWiki Integration: wiki_doku_id aus Name+Modell, zentraler Namespace konfigurierbar
- wiki_doku_id wird nun aus equipment.name und equipment.model kombiniert generiert
- Systemparameter 'dokuwiki.central_documentation_namespace' für konfigurierbaren Namespace
- Verbessertes Error-Handling in dokuwiki_client mit detaillierteren Fehlermeldungen
- Docker-Netzwerk Unterstützung dokumentiert
- Gelöschte veraltete WordPress-API Dateien
2025-12-23 14:48:44 +01:00
253d289633 feat(dokuwiki): Flexible overview table with configurable columns
- Made overview table columns fully configurable via system parameters
- Added wiki_page_id placeholder for internal DokuWiki links
- Removed DokuWiki template dependency for overview table
- Added _register_hook to initialize parameters on module load/update
- Updated README with new configuration approach
- System parameters: overview_page_id, overview_title, overview_columns, overview_column_data
- Default columns: Name (with link), Status, Security Category, Area, Location, Image
2025-12-20 12:49:58 +01:00
de317f46e6 feat(dokuwiki): Add equipment overview table with DataTables
- Add _generate_overview_table_row() to generate table row per equipment
- Add action_sync_overview_table() for fast overview page sync
- Add new sync mode 'Übersichtstabelle aktualisieren' in wizard
- Add config parameters for overview page and template IDs
- Add overview_url field to wizard result view
- Columns: Name (linked), Status, Security Category, Area, Location, Image
- Performance: Single page update without iterating all equipment
- Include DokuWiki template and setup documentation
- Requires DokuWiki DataTables plugin for sortable/filterable table
- Fix: Use status_id instead of equipment_status_id
2025-12-19 20:40:29 +01:00
8ae586cca6 feat: Auto-create ows.machine on equipment import/create
- Add @api.model_create_multi hook to MaintenanceEquipment.create()
- Add load() override to handle Excel/CSV import correctly
- Add _create_missing_ows_machines() helper with recursion prevention
- Modify OwsMachine.create() to only create equipment if equipment_id not provided
- Use context flag 'skip_ows_machine_creation' to prevent infinite recursion
- Fixes: Equipment import now auto-creates ows.machine and displays OWS tab
- Migration tested: Compatible with SQL-based post-migration (23/23 machines migrated)
2025-12-19 20:12:54 +01:00
e18f2880a4 Make post-migration.py more robust when setting default status
- Check if status 'In Betrieb' exists before setting it
- Add warning if status not found instead of SQL error
- Status records are created automatically via XML data file
2025-12-18 20:56:14 +01:00
43cf5754fd Add automated maintenance equipment status creation with smileys
- open_workshop_base: Create 4 status records (In Betrieb, Defekt, Wartung, Ausgemustert) via XML data
- open_workshop_dokuwiki: Add smiley field to status model and populate with DokuWiki smileys/emojis
- Use noupdate=1 to prevent overwriting user customizations
- Status data loads automatically during module installation
2025-12-18 20:53:04 +01:00
4c048b5ca9 fix(ows_models): Update create() to use @api.model_create_multi for Odoo 18
Fixed DeprecationWarning by updating OwsMachine.create() method:
- Changed from @api.model with single vals parameter
- To @api.model_create_multi with vals_list parameter
- Now supports batch creation of multiple records
- Removed duplicate empty OwsMachineArea class definition

This resolves the Odoo 18 deprecation warning about create method not supporting batch operations.
2025-12-15 20:55:36 +01:00
686b201792 docs(migration): Add comments explaining related field synchronization
Added documentation to clarify:
- Why store=True is used for related fields (performance for filtering/searching)
- Why manual synchronization is needed in migration (related fields don't auto-sync during SQL INSERT)

No functional changes, only improved code documentation.
2025-12-15 20:46:14 +01:00
bd235e3ca0 fix(migration): Synchronize related fields (area_id, category) from ows.machine to maintenance.equipment
The related fields in maintenance.equipment with store=True were not automatically
synchronized during migration. Added explicit SQL UPDATE statements to copy values:
- ows_area_id from area_id
- ows_category from category

This ensures the maintenance.equipment records have all the OWS-specific data
from the original ows.machine records after migration.
2025-12-15 20:36:41 +01:00
a5f8fd32c3 feat(dokuwiki): Add partner fields, editable smileys, category icon, and mass sync wizard
- Add partner_id and partner_ref template placeholders for supplier information
- Implement editable status smiley field in maintenance.equipment.status
- Add UI views for editing smileys in Odoo (Wartung → Konfiguration → Equipment Status)
- Fix category field bug: use ows_category instead of category_id for security category
- Add category_icon placeholder displaying emoji indicators (🔴/🟡/🟢)
- Implement mass synchronization wizard (Wartung → Konfiguration → Wiki-Synchronisation)
  - Sync all equipment or filter by area
  - Sync only unsynchronized equipment
  - Force-sync option to overwrite existing documentation pages
  - Statistics display with error reporting
- Add security access rules for wizard
- Update README with new placeholders
2025-12-14 20:55:21 +01:00
3fa050f153 feat(dokuwiki): Add wiki-based template system and image upload
- Implemented wiki-based template system using c_template
  - Template loaded from werkstatt:ausruestung:c_template
  - Placeholder replacement for all equipment and related fields
  - Fallback to hardcoded content if template unavailable
  - Only view pages use templates, central doku page unchanged

- Added image upload capability for equipment
  - New field: image_1920 (Image field, max 1920x1920px)
  - View integration: Positioned as avatar before button_box
  - Upload to DokuWiki media directory during sync
  - Temporary file approach for dokuwiki.py library compatibility

- Extended template placeholders:
  - status: Equipment status from status_id
  - odoo_link: Formatted link back to Odoo equipment form
  - odoo_url: Direct URL to equipment in Odoo
  - image: Equipment image (300px width)
  - image_large: Equipment image (original size)
  - image_id: Media path for custom DokuWiki syntax

- Updated documentation with all available placeholders
2025-12-13 23:02:49 +01:00
e53c4028c9 feat(dokuwiki): Implement single-page DokuWiki integration
- Simplified architecture: ONE central documentation page per equipment
- Wiki ID generation from equipment name (e.g., 'sabako-laser')
- Namespace structure: werkstatt:ausruestung:doku:{name}
- View pages by area: werkstatt:ausruestung:{area}:{name}
- Smart page protection: central doku only created once, not overwritten
- View pages update on each sync (shows current Odoo metadata)
- Template detection: distinguishes real content from DokuWiki auto-templates
- JSONB multilingual name field handling
- Include Plugin integration for embedded content display
- Automatic sync option via write() override
- Configuration via System Parameters (url, user, password)
- Settings page in General Settings for easy credential management
2025-12-13 21:50:19 +01:00
5057985024 docs(feature-plan): Change namespace to werkstatt:ausruestung and add initial ACL phase
- Changed namespace from ausruestung:* to werkstatt:ausruestung:*
  - Main pages: werkstatt:ausruestung:bereich:maschinenname
  - Doku pages: werkstatt:ausruestung:bereich:maschinenname:doku

- Added two-phase ACL approach:
  - Phase 1: Only @odoo has access (initial setup/testing)
    - werkstatt:ausruestung:* @odoo 8
    - werkstatt:ausruestung:* @ALL 0
  - Phase 2: Werkstatt gets read/edit access (later rollout)
    - Main pages: @werkstatt read-only
    - Doku pages: @werkstatt editable

- Updated all code examples with new namespace
- Updated ACL permission table
- Added phased rollout advantage
2025-12-13 19:23:11 +01:00
00f33faebe docs(feature-plan): Refine DokuWiki architecture - inverted include approach
- Changed from marker-based sync to inverted include architecture:
  - Odoo generates read-only main page with equipment data
  - Main page includes user-editable :doku subpage via Include Plugin
  - Clear separation: Odoo owns structure, users own documentation

- Two-page system per equipment:
  - ausruestung:bereich:maschine (Odoo-generated, read-only)
  - ausruestung:bereich:maschine:doku (user-editable)

- Generisches ACL-System (maintenance-free):
  - ausruestung:*:doku @werkstatt 2 (editable)
  - ausruestung:* @werkstatt 1 (read-only)
  - Works automatically for all equipment

- Simplified sync algorithm:
  - Odoo completely overwrites main page (no marker parsing)
  - User content protected on separate page
  - Include renders both seamlessly

- Added detailed Python code examples
- Documented ACL wildcard matching rules
- Added table showing permission resolution

Benefits:
- No risk of users deleting sync markers
- Users cannot accidentally break Odoo data
- Self-healing: Odoo always regenerates correct structure
- Scalable: Works for 1000+ equipment pages
2025-12-13 18:16:33 +01:00
2eff81ce54 docs(feature-plan): Clarify sync mechanism - unidirectional with protected sections
- Changed 'bidirektional' to 'unidirektional' (Odoo → DokuWiki)
- Clarified data ownership:
  - Odoo = Master for structured data (name, serial_no, area, category)
  - DokuWiki = Master for freetext documentation (manuals, tips)

- Added sync marker system:
  - <- Ensures POS functionality is activated after ODOO_SYNC_START: section_name -->
  - <- Ensures POS functionality is activated after ODOO_SYNC_END: section_name -->
  - Only content between markers gets updated by Odoo
  - All other sections (Bedienung, Tipps & Tricks) remain untouched

- Documented sync algorithm with Python code example
- Users can freely edit wiki without fear of data loss
- DokuWiki versioning preserves all changes
2025-12-13 17:53:54 +01:00
92490aeb9c docs(feature-plan): Replace WordPress with DokuWiki integration
- Replaced open_workshop_api (WordPress REST API) with open_workshop_dokuwiki
- DokuWiki chosen for equipment documentation:
  - File-based, no separate database needed
  - Built-in versioning and history
  - Wiki syntax perfect for technical docs
  - Granular ACL (Odoo writable, all readable)
  - XML-RPC API for bidirectional sync

- Planned DokuWiki features:
  - Automatic wiki page per equipment
  - Namespace structure: ausruestung:bereich:maschinenname
  - Template system with equipment data
  - Smart button 'Wiki öffnen' in Equipment form
  - Auto-sync on equipment changes

- WordPress integration now optional:
  - Can be added later for public presentation
  - DokuWiki handles documentation (priority)
  - WordPress for marketing/SEO (future)

- Updated architecture diagram and implementation status
- open_workshop_api moved to 'optional' status
2025-12-13 17:50:51 +01:00
1b203eeb10 feat(equipment-view): Integrate OWS into Maintenance menu with Equipment-centric views
- Extended maintenance.equipment model with Related fields to ows.machine
  - ows_machine_id: One2many inverse relation
  - ows_category: Related to machine category (editable, stored)
  - ows_area_id: Related to machine area (editable, stored)
  - ows_product_ids: Related One2many for usage products
  - ows_training_ids: Related One2many for training products

- Equipment Form View Extensions:
  - Added ows_area_id and ows_category after location field
  - New 'Offene Werkstatt (Hobbyhimmel)' notebook page with:
    - Security section (category icon, category, area)
    - Usage products section (Nutzungsprodukte)
    - Training products section (Einweisungsprodukte)
  - Page visibility controlled by ows_machine_id existence

- Equipment List/Search View Extensions:
  - Added ows_category_icon and ows_area_id columns
  - Added OWS search fields (area, category)
  - Added category filters (green/yellow/red)
  - Added OWS grouping options (by area, by category)

- Menu Structure Migration:
  - Removed standalone 'Ausrüstung' top-level menu
  - Integrated all OWS config into Maintenance → Configuration:
    - Bereiche (Areas)
    - Zuordnungen (Assignments) container
      - Nutzungsprodukte (Usage Products)
      - Einweisungsprodukte (Training Products)

- Created simplified tree views for Equipment context:
  - view_ows_machine_product_tree_simple (no machine_id column)
  - view_ows_machine_training_tree_simple (no machine_id column)

- Freed location field from automatic area synchronization:
  - Removed area → location mapping in create()/write()
  - location now available for detailed physical location info
  - ows_area_id provides workspace area assignment

BREAKING CHANGE: Standalone OWS menu removed, all features now in Maintenance app
UX IMPROVEMENT: Single Equipment view shows all data, no split views needed
2025-12-13 17:43:07 +01:00
ed339b0e2e feat(open_workshop_base): Erweiterte Search-View und Gruppierung
- Füge maintenance.equipment Felder zur Suche hinzu (model, partner_id, location, company_id)
- Erweitere Gruppierungsoptionen (Hersteller, Techniker, Standort)
- Standard-Gruppierung nach Bereich aktiviert
- Dokumentation: _inherits Pattern erklärt in Feature Plan
2025-12-13 14:38:42 +01:00
e1feeb6d75 feat(aspl_equipment_qrcode_generator): Fix QR-code generation and PDF rendering
- Move QR-code generation from report to wizard (before PDF generation)
- Add attachment=True to qr_code Binary field for filestore storage
- Simplify report class - only provides data, no QR generation
- Change template from t-field to <img> with base64 data URL for proper PDF rendering
- Fix JSONB field extraction (name, category) for de_DE/en_US
- Add equipment_ids field to wizard form (invisible)
- Apply changes to all 3 label formats (2x5, 2x7, 4x7)

QR-codes now display correctly in generated PDFs and contain equipment
details plus direct link to Odoo equipment record.
2025-12-11 21:53:21 +01:00
550cdac1eb fix: Set company_id in equipment migration to fix serial number generation
- Add default company_id to equipment records during migration
- Fixes 'Generate Serial Number' button not working for migrated equipment
- Equipment without company_id could not generate serial numbers
2025-12-11 19:22:52 +01:00
b68ac293c8 added qrcode for equipment modul 2025-12-11 19:19:02 +01:00
42db76a9c7 feat: Improve equipment creation flow and UX
- Made location field readonly in maintenance.equipment view
- Hide equipment_id field in machine form (auto-created)
- Name and serial_no now directly editable in machine form
- Area is now required field
- Location automatically synced from area to equipment
- Equipment auto-created on machine save with all fields
- Renamed menu from 'Maschinen' to 'Ausrüstung'
- Improved user flow: No need to switch between views

Changes:
- Added maintenance_equipment_views.xml for readonly location
- Updated create() to always auto-create equipment
- Enhanced write() to sync name/serial_no changes to equipment
- Menu labels updated to 'Ausrüstung'
2025-12-07 21:33:06 +01:00
f87755e7d0 Merge branch '18.0-MultiModulOpenWorkshop' into 18.0
Integration of maintenance.equipment with automated migration workflow
2025-12-07 21:10:35 +01:00
8fb58c744e feat: Migrate to maintenance.equipment with automated OpenUpgrade workflow
- Integrated maintenance.equipment using _inherits pattern in open_workshop_base
- Removed duplicate fields (code, description, storage_location, purchase_price, purchase_date)
- Delegated equipment management to OCA maintenance module
- Added Smart Button UI pattern for equipment details
- Implemented automated migration workflow:
  * SQL script renames module open_workshop → open_workshop_base
  * Pre-migration: Installs maintenance, adds equipment_id column
  * Post-migration: Migrates 23 machines with proper JSONB names and locations
- Restored old open_workshop module (installable=False) for DB compatibility
- Updated CI/CD workflow with migration steps
- Area mapping corrected: area.name → equipment.location
- JSONB handling: Using SQL jsonb_build_object() for proper storage
- Serial numbers: From old code field or generated as OWS-{id}

Tested and verified:
 23 machines successfully migrated
 JSONB names extractable: name->>'de_DE' and name->>'en_US'
 Locations correctly mapped: Fablab, Holzbereich, etc.
 equipment_id linkage functional
2025-12-07 21:09:35 +01:00
ceb8af7e48 Fix: POS Template - duplicate key error in ows_pos_customer_sidebar
- t-key fallback: order.uid || order.id || order_index
- Verhindert 'undefined' duplicate key error im POS
- Asset-Bundle korrigiert: point_of_sale._assets_pos
2025-12-07 17:18:09 +01:00
71c6ba56ed Kapitel 3+4: POS-Code in separates Modul ausgelagert
- Neues Modul open_workshop_pos erstellt
- POS JavaScript, XML Templates und CSS verschoben
- open_workshop_base bereinigt: keine POS-Abhängigkeit mehr
- open_workshop_base Version 18.0.1.0.4
- open_workshop_pos Version 18.0.1.0.0
- Kategorie von 'Point of Sale' zu 'Manufacturing' geändert
- Alle Template-Referenzen aktualisiert (open_workshop_base → open_workshop_pos)

Module getestet und erfolgreich installiert in hh18 Datenbank.
2025-12-07 16:43:51 +01:00
744b7b3234 Merge branch '18.0-MultiModulOpenWorkshop': Migration open_workshop → open_workshop_base 2025-12-07 16:01:51 +01:00
3619526af0 Migration: open_workshop → open_workshop_base
- Modul umbenannt von open_workshop zu open_workshop_base
- Alle Referenzen im Code aktualisiert (Templates, Views, Assets)
- SQL-Migrationsskript für automatische DB-Migration erstellt
- post_init_hook hinzugefügt
- Version auf 18.0.1.0.3 erhöht
- Vorbereitung für modulare Architektur (Base, POS, API)

Fixes für Gitea Action Integration:
- SQL-Skript in open_workshop_base/migrations/
- Alter open_workshop/ Ordner entfernt
- Migrations-Workflow getestet auf hh18
2025-12-07 15:45:03 +01:00
bb3d1bf7c9 removed unused files 2025-12-07 15:00:15 +01:00
bf605539fa final feature request 2 2025-12-07 14:53:06 +01:00
12d5902e3c final feature request 1 2025-12-07 14:50:36 +01:00
977aa2d1b3 final feature request 2025-12-07 14:46:09 +01:00
58c7e8f258 Open Workshop Multi Module Refactoring 2025-12-07 14:03:32 +01:00
7cd458b72f This now a multi modul odoo repository, open_workshop moved to open_workshop_base 2025-12-06 20:45:29 +01:00
dff2de1755 FIX: pos: wenn auf - gedrückt wird um eine Order zu entfernen, wurde nicht
die Order nicht gefunden. -> behoben
- IMP: "einfachere" Debug Möglichkeit mit odoo-18-dev container. README.md in .vscode
  hinzugefügt.
2025-10-25 14:10:25 +02:00
d56ae65b56 fixed missing dependency 2025-10-24 20:15:44 +02:00
bc0459ab9b IMP: added work_email to admin employee 2025-10-11 11:23:50 +02:00
7230bcb6f8 fix: anonymize_for_testsystem now supports archived admin account 2025-10-10 19:56:49 +02:00
f07f9dd8b3 Fix Odoo 18 compatibility: Enable notebook widget and fix context references
- Uncomment and activate notebook widget in machine form view
- Fix context reference from 'active_id' to 'id' for Odoo 18 compatibility
- Remove duplicate category_icon field in form group
- Clean up XML structure and indentation
- Enable "Nutzungsprodukte" and "Einweisungsprodukte" tabs with editable lists
- Resolve access rights inconsistency error for product_ids field

Fixes module upgrade error: "Field 'active_id' does not exist in model 'ows.machine'"
2025-10-09 22:17:09 +02:00
5c7fd4330d removed debugpy 2025-10-07 18:27:40 +02:00
ab696db035 Duplicate Warning Patch 2025-10-07 17:34:34 +02:00
1069630e86 FIX: Add VS Code debugging configuration and fix pos_order.py
- Added .vscode/launch.json with remote debugging setup for Odoo development
- Configured debugpy attachment on port 4338 with path mappings
- Added workspace settings for Python development with Odoo
- Fixed issues in pos_order.py for improved POS functionality
- Enhanced development workflow with breakpoint support for custom code and Odoo core
2025-10-06 19:54:24 +02:00
558dff276a debugpy option 2025-10-05 20:52:04 +02:00
e0a9205fea [fix] res.partner.remove.duplicate.bank.warning 2025-08-07 19:30:26 +02:00
24baff2a86 [fix] typo fehler 2025-08-07 19:26:37 +02:00
62dbf92b36 [fix] unknown res.partner.remove.duplicate.bank.warning 2025-08-07 19:21:34 +02:00
bbb5181a74 Merge pull request 'fix for duplicate_bank_partner_ids in account modul' (#9) from 18.0-target into 18.0
Reviewed-on: #9
2025-07-13 14:37:07 +02:00
05f9ef0990 fix for duplicate_bank_partner_ids in account modul 2025-07-13 14:32:50 +02:00
33db478c72 Merge pull request 'removeCurrentOrder() fix' (#8) from 18.0-target into 18.0
Reviewed-on: #8
2025-07-06 14:54:50 +02:00
7e8840f2a5 removeCurrentOrder() fix 2025-07-06 14:53:37 +02:00
d4a835f178 Merge pull request '18.0-target' (#7) from 18.0-target into 18.0
Reviewed-on: #7
2025-07-01 22:08:25 +02:00
0fe8417602 running POS ows machine access and customer sidebar 2025-07-01 21:57:51 +02:00
1f59e16b26 working with pos sidebar, but no content 2025-06-28 21:58:58 +02:00
59e4b19dee almost done for POS 2025-06-28 18:49:49 +02:00
021d01efe6 working merge with open_workshop 17.0. Missing Traings view in Machine Backend. No POS Machine sidebar. 2025-06-28 15:31:59 +02:00
f4216d790c added todo 2025-05-02 08:06:03 +02:00
eb17894a13 minimale Version von open workshop v16.0 für migration 2025-05-01 15:33:35 +02:00
292 changed files with 41322 additions and 4223 deletions

View File

@ -0,0 +1,15 @@
{
"name": "Open Workshop (Odoo Dev)",
"dockerComposeFile": ["${localWorkspaceFolder}/../../odoo/docker-compose.dev.yaml"],
"service": "odoo-dev",
"workspaceFolder": "/mnt/extra-addons/open_workshop",
"runServices": ["odoo-dev", "db"],
"shutdownAction": "stopCompose",
"remoteUser": "root",
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance"
],
"forwardPorts": [4338],
"postStartCommand": "echo 'Devcontainer started'"
}

8
.env
View File

@ -1,8 +0,0 @@
ODOO_VERSION=13.0
CONTAINER_NAME_EXTENSION=13_dev
ODOO_PORT=9013
DB_HOST=hobbyhimmel_odoo_13_dev_db
DB_PORT=5432
DB_USER=odoo
DB_PASSWORD=odoo
DB_NAME=hobbyhimmel

View File

@ -1,69 +0,0 @@
name: POS Test Feedback
about: Rückmeldung zu einem Test des POS-Systems geben
title: "[Feedback] "
labels: [feedback, test]
assignees: []
body:
- type: markdown
attributes:
value: |
## 🧪 POS-Test: Feedbackformular
Bitte gib uns Rückmeldung zu den einzelnen Funktionen. Beschreibe ggf. Probleme oder Auffälligkeiten.
- type: textarea
id: sonstiges
attributes:
label: Sonstiges Feedback oder Fehler
description: Alles andere, was dir beim Test aufgefallen ist (z.B. Layout, Ladezeiten, Fehlermeldungen).
- type: textarea
id: nutzerauswahl
attributes:
label: Nutzer auswählen
description: Funktioniert die Auswahl des Nutzers im POS wie erwartet?
placeholder: z.B. Nutzer nicht auffindbar, Anzeige langsam etc.
- type: textarea
id: haftung
attributes:
label: Haftungsausschluss prüfen
description: Wird der Haftungsausschluss korrekt angezeigt bzw. berücksichtigt?
- type: textarea
id: maschinenfreigabe
attributes:
label: Maschinenfreigabe prüfen
description: Wird korrekt angezeigt, ob der Nutzer eine Einweisung für eine Maschine hat?
- type: textarea
id: abrechnung
attributes:
label: Abrechnung (Bargeld / SumUp)
description: Funktioniert die Abrechnung für den Nutzer?
- type: textarea
id: coupon
attributes:
label: Coupons (erstellen / einlösen)
description: Funktionieren Erstellen und Einlösen von Coupons korrekt?
- type: textarea
id: nutzerdaten
attributes:
label: Nutzerdaten aktualisieren / Haftungsausschluss abwählen
description: Lassen sich Nutzerdaten wie RFID oder der Haftungsausschluss korrekt ändern?
- type: textarea
id: einweisung
attributes:
label: Einweisung verkaufen / prüfen
description: Lässt sich eine Einweisung verkaufen und wird sie korrekt zugewiesen?
- type: textarea
id: backend
attributes:
label: Backend-Funktionen
description: Können Maschinen und Einweisungen im Backend wie erwartet verwaltet werden?

7
.gitignore vendored
View File

@ -15,7 +15,7 @@ dist/
downloads/ downloads/
eggs/ eggs/
.eggs/ .eggs/
lib/ #lib/
lib64/ lib64/
parts/ parts/
sdist/ sdist/
@ -159,3 +159,8 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
# DokuWiki API Test Script (enthält Credentials)
test_dokuwiki.py
# Python Virtual Environment
venv/

289
.vscode/.jslintrc vendored Normal file
View File

@ -0,0 +1,289 @@
{
"globals": {
"$": false,
"_": false,
"fuzzy": false,
"jQuery": false,
"moment": false,
"odoo": false,
"openerp": false,
"self": false
},
"env": {
"browser": true
},
"rules": {
"no-alert": "error",
"no-array-constructor": "error",
"no-bitwise": "off",
"no-caller": "error",
"no-case-declarations": "error",
"no-catch-shadow": "error",
"no-class-assign": "error",
"no-cond-assign": "error",
"no-confusing-arrow": "error",
"no-console": "error",
"no-const-assign": "error",
"no-constant-condition": "error",
"no-continue": "off",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-div-regex": "error",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-duplicate-imports": "error",
"no-else-return": "error",
"no-empty": "error",
"no-empty-character-class": "error",
"no-empty-function": "error",
"no-empty-pattern": "error",
"no-eq-null": "error",
"no-eval": "error",
"no-ex-assign": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-boolean-cast": "error",
"no-extra-label": "error",
"no-extra-parens": "error",
"no-extra-semi": "error",
"no-fallthrough": "error",
"no-floating-decimal": "error",
"no-func-assign": "error",
"no-implicit-coercion": ["error", {
"allow": ["~"]
}],
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-inline-comments": "error",
"no-inner-declarations": "error",
"no-invalid-regexp": "error",
"no-invalid-this": "off",
"no-irregular-whitespace": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "off",
"no-magic-numbers": "off",
"no-mixed-operators": "error",
"no-mixed-requires": "error",
"no-mixed-spaces-and-tabs": "error",
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-native-reassign": "error",
"no-negated-condition": "error",
"no-negated-in-lhs": "error",
"no-nested-ternary": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-require": "error",
"no-new-symbol": "error",
"no-new-wrappers": "error",
"no-obj-calls": "error",
"no-octal": "error",
"no-octal-escape": "error",
"no-param-reassign": "error",
"no-path-concat": "error",
"no-plusplus": "off",
"no-process-env": "error",
"no-process-exit": "error",
"no-proto": "error",
"no-prototype-builtins": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-restricted-globals": "error",
"no-restricted-imports": "error",
"no-restricted-modules": "error",
"no-restricted-syntax": "error",
"no-return-assign": "error",
"no-script-url": "error",
"no-self-assign": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow": "error",
"no-shadow-restricted-names": "error",
"no-whitespace-before-property": "error",
"no-spaced-func": "error",
"no-sparse-arrays": "error",
"no-sync": "error",
"no-tabs": "error",
"no-ternary": "off",
"no-trailing-spaces": "error",
"no-this-before-super": "error",
"no-throw-literal": "error",
"no-undef": "error",
"no-undef-init": "error",
"no-undefined": "off",
"no-unexpected-multiline": "error",
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "error",
"no-unreachable": "error",
"no-unsafe-finally": "error",
"no-unused-expressions": "error",
"no-unused-labels": "error",
"no-unused-vars": "error",
"no-use-before-define": "error",
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-escape": "error",
"no-useless-rename": "error",
"no-void": "error",
"no-var": "off",
"no-warning-comments": "off",
"no-with": "error",
"array-bracket-spacing": "off",
"array-callback-return": "error",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "off",
"accessor-pairs": "error",
"block-scoped-var": "off",
"block-spacing": ["error", "always"],
"brace-style": "error",
"callback-return": "error",
"camelcase": "off",
"capitalized-comments": ["error", "always", {
"ignoreConsecutiveComments": true,
"ignoreInlineComments": true
}],
"comma-dangle": ["error", "always-multiline"],
"comma-spacing": ["error", {
"before": false,
"after": true
}],
"comma-style": "error",
"complexity": [
"error",
15
],
"computed-property-spacing": "off",
"consistent-return": "off",
"consistent-this": "off",
"constructor-super": "error",
"curly": "error",
"default-case": "off",
"dot-location": ["error", "property"],
"dot-notation": "error",
"eol-last": "error",
"eqeqeq": "error",
"func-names": "off",
"func-style": "off",
"generator-star-spacing": "off",
"global-require": "error",
"guard-for-in": "off",
"handle-callback-err": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"indent": "error",
"init-declarations": "error",
"jsx-quotes": "error",
"key-spacing": "off",
"keyword-spacing": "error",
"linebreak-style": [
"error",
"unix"
],
"lines-around-comment": "error",
"max-depth": "error",
"max-len": ["error", {
"code": 80,
"ignorePattern": "odoo\\.define\\(",
"tabWidth": 4
}],
"max-lines": "off",
"max-nested-callbacks": "error",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "error",
"multiline-ternary": "off",
"new-cap": "off",
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"object-curly-newline": ["error", { "consistent": true }],
"object-curly-spacing": ["error", "never"],
"object-property-newline": ["error", {
"allowAllPropertiesOnSameLine": true
}],
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": "off",
"operator-assignment": "error",
"operator-linebreak": "error",
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": "error",
"require-yield": "error",
"rest-spread-spacing": "off",
"semi": [
"error",
"always"
],
"semi-spacing": "error",
"sort-imports": "error",
"sort-vars": "off",
"space-before-blocks": "error",
"space-before-function-paren": "error",
"space-in-parens": "off",
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": ["error", "always"],
"strict": ["error", "function"],
"template-curly-spacing": "off",
"unicode-bom": "error",
"use-isnan": "error",
"valid-jsdoc": ["error", {
"prefer": {
"arg": "param",
"argument": "param",
"augments": "extends",
"constructor": "class",
"exception": "throws",
"func": "function",
"method": "function",
"prop": "property",
"return": "returns",
"virtual": "abstract",
"yield": "yields"
},
"preferType": {
"array": "Array",
"bool": "Boolean",
"boolean": "Boolean",
"number": "Number",
"object": "Object",
"str": "String",
"string": "String"
},
"requireParamDescription": false,
"requireReturn": false,
"requireReturnDescription": false,
"requireReturnType": false
}],
"valid-typeof": "error",
"vars-on-top": "off",
"wrap-iife": "error",
"wrap-regex": "error",
"yield-star-spacing": "off",
"yoda": "error"
},
"parserOptions": {}
}

64
.vscode/README.md vendored Normal file
View File

@ -0,0 +1,64 @@
# Quickstart: Debugging für open_workshop
Diese Datei hilft dir, das `open_workshop` Addon schnell in VS Code zu öffnen und sowohl das Addon als auch (optional) den OdooCore zu debuggen.
Kurzfassung
- Öffne in VS Code den Ordner `extra-addons/open_workshop`.
- Starte die Development-Container/Composer Umgebung mit `./dev.sh` (Option 1 oder 2).
- Verwende die DevContainerFunktion oder die DebugKonfigurationen unten.
1) Container starten
Empfohlen: im Projektstamm (`odoo`) ausführen:
```bash
./dev.sh
# Option 1: Normal starten (ODOO_DEV=1)
# Option 2: Debug-Modus (ODOO_DEBUG=1) — der Container wartet auf eine Debug-Verbindung
```
2) VS Code als DevContainer verbinden (empfohlen)
- Öffne VS Code im lokalen Ordner `extra-addons/open_workshop`.
- Command Palette → `Dev Containers: Attach to Running Container...` → wähle `odoo-dev`.
- VS Code öffnet den Container als Arbeitsumgebung (remoteUser ist `odoo`).
- Öffne dann das WorkspaceVerzeichnis `/mnt/extra-addons/open_workshop`.
Vorteil: Du arbeitest direkt im Container (kein lokales Kopieren der CoreSourcen nötig) und Breakpoints funktionieren zuverlässig.
3) Debugging (Attach)
- Wenn du als DevContainer verbunden bist, verwende die DebugKonfiguration "Odoo Attach (container)" (port 5678).
- Wenn du lokal arbeitest und den HostPort benutzt, verwende "Odoo Attach (host)" (port 4338).
4) PfadMapping
- Die `launch.json` enthält Pfadabbildungen:
- `${workspaceFolder}``/mnt/extra-addons/open_workshop` (dein Addon)
- `${workspaceFolder}/../../odoo-source/odoo``/usr/lib/python3/dist-packages/odoo` (falls du lokal eine Kopie des OdooCores hast)
Hinweis: Lokale `odoo-source` ist nicht erforderlich, wenn du per DevContainer arbeitest, weil VS Code die Dateien direkt im Container liest.
5) Troubleshooting
- Debug-Verbindung schlägt fehl: prüfe, ob der Container im DebugModus läuft und der Port gemappt ist:
```bash
docker compose -f docker-compose.dev.yaml ps
docker compose -f docker-compose.dev.yaml logs -f odoo-dev
```
- VS Code meldet, dass Breakpoints nicht aufgelöst werden: vergewissere dich, dass die `pathMappings` korrekt sind und die lokalen Dateien existieren (oder nutze DevContainer).
6) Image/Compose aktualisieren
- Wenn du `Dockerfile.Dev` geändert hast: neu bauen (Option 3 in `./dev.sh`), dann Container neu starten (Option 5 oder down/up).
7) Kurze Checklist für Mitentwickler
- `./dev.sh` → Option 3 (einmalig) wenn du das DevImage bauen musst.
- `./dev.sh` → Option 1 oder 2 zum Starten.
- In VS Code: Öffne `extra-addons/open_workshop`, dann `Dev Containers: Attach to Running Container...`.
- Starte Debug mit "Odoo Attach (container)" oder "Odoo Attach (host)".

45
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,45 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Odoo Attach (host)",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 4338
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/mnt/extra-addons/open_workshop"
},
{
"localRoot": "${workspaceFolder}/../../odoo-source/odoo",
"remoteRoot": "/usr/lib/python3/dist-packages/odoo"
}
],
"justMyCode": false
},
{
"name": "Odoo Attach (container)",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/mnt/extra-addons/open_workshop"
},
{
"localRoot": "${workspaceFolder}/../../odoo-source/odoo",
"remoteRoot": "/usr/lib/python3/dist-packages/odoo"
}
],
"justMyCode": false
}
]
}

30
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
"python.pythonPath": "/usr/bin/python3",
"python.analysis.extraPaths": [
"${workspaceFolder}",
"${workspaceFolder}/../../odoo-source/odoo"
],
"python.analysis.typeCheckingMode": "off"
}
{
"editor.rulers": [80, 100, 120],
"files.eol": "\n",
"[python]": {
"editor.defaultFormatter": "ms-python.python",
"editor.insertSpaces": true,
"editor.tabSize": 4
},
"[javascript]": {
"editor.insertSpaces": true,
"editor.tabSize": 2
},
"python.analysis.extraPaths": [
"../../odoo-source/odoo",
],
"python.testing.pytestArgs": [
"--odoo-http",
"."
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": false
}

68
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,68 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "start-odoo-dev",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../../odoo/docker-compose.dev.yaml", "up", "-d"],
"options": {
"env": {
"ODOO_DEV": "1"
}
},
"group": { "kind": "build", "isDefault": true },
"presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" },
"problemMatcher": []
},
{
"label": "start-odoo-debug",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../../odoo/docker-compose.dev.yaml", "up", "-d"],
"options": {
"env": {
"ODOO_DEBUG": "1"
}
},
"group": "build",
"presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" },
"problemMatcher": []
},
{
"label": "rebuild-odoo-dev",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../../odoo/docker-compose.dev.yaml", "up", "--build", "-d"],
"group": "build",
"presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" },
"problemMatcher": []
},
{
"label": "stop-odoo-dev",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../..odoo/docker-compose.dev.yaml", "down"],
"group": "build",
"presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" },
"problemMatcher": []
},
{
"label": "odoo-logs",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../../odoo/docker-compose.dev.yaml", "logs", "-f", "odoo-dev"],
"group": "test",
"presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" },
"problemMatcher": []
},
{
"label": "shell-odoo",
"type": "shell",
"command": "docker",
"args": ["compose", "-f", "${workspaceFolder}/../../odoo/docker-compose.dev.yaml", "exec", "odoo-dev", "bash"],
"presentation": { "echo": true, "reveal": "always", "focus": true, "panel": "shared" },
"problemMatcher": []
}
]
}

View File

@ -0,0 +1,178 @@
# Odoo vs WordPress vs Odoo.sh Architektur- & Strategie-Empfehlung
*Für HobbyHimmel / FabLab Traffic: ~1000 Besucher, 2000 Views pro Tag*
---
# 🚀 Zusammenfassung (TL;DR)
| Bereich | Empfehlung |
|--------|------------|
| Öffentliche Website | **WordPress behalten** |
| Odoo als öffentliche Website | **Nicht geeignet** (Performance + Security) |
| Odoo.sh | **Nicht geeignet** (Benutzerkosten, Einschränkungen) |
| Odoo self-hosted | **Optimal für interne Prozesse** |
| Integration | **WordPress ↔ Odoo via REST API** |
| Zielarchitektur | **WP Frontend + Odoo Backend** |
---
# 1. Zielsetzung
HobbyHimmel benötigt:
- Eine öffentliche Website (ca. 1000 Besucher / 2000 Views täglich)
- Interne Verwaltungsprozesse (Maschinen, Einweisungen, Kurse, POS)
- Möglichkeit, ausgewählte Daten (Maschinenstatus, Kurstermine…) öffentlich darzustellen
- Möglichst geringe Kosten
- Hohe Sicherheit (keine offene interne Datenbank)
---
# 2. Analyse der drei Optionen
## 2.1 WordPress (beste Lösung für öffentliche Webseite)
**Stärken:**
- Sehr schneller Seitenaufbau, Caching, CDN
- Perfekt für hohe Besucherzahlen
- Themes, SEO, Plug-ins
- Komplett getrennt vom internen FabLab-System
**Schwächen:**
- Kein direkter Zugriff auf Odoo-Daten (muss über API geschehen)
**Fazit:**
⭐⭐⭐⭐⭐ **Beste Lösung für alle öffentlichen Besucher.**
---
## 2.2 Odoo (self-hosted, intern)
**Stärken:**
- Ideal für Maschinenverwaltung, POS, Maintenance, Events
- Volle Freiheit, beliebige Module zu installieren
- Keine Lizenzkosten für Ehrenamtliche, solange sie keinen Login benötigen
- Perfekt für interne Daten & Prozesse
**Schwächen:**
- Als öffentliche Website ungeeignet (Performance, kein CDN)
- DSL-Upload wäre Flaschenhals
**Fazit:**
⭐⭐⭐⭐⭐ **Beste Lösung für interne Prozesse.
Nicht geeignet als öffentliche Website.**
---
## 2.3 Odoo.sh
**Vorteile:**
- Kein DSL-Problem
- Hosting, Deployment & Backups werden automatisiert
**ABER:**
- **sehr hohe Kosten** bei >10 Ehrenamtlichen (pro Benutzer Lizenzpflicht)
- **stark eingeschränkt** bei Custom-Code, Addons, APIs
- Performance besser, aber **immer noch weit unter WordPress**
- Website-Teil ist **nicht auf hohen Traffic optimiert**
**Fazit:**
⭐⭐ **Für HobbyHimmel ungeeignet.**
Zu teuer, zu eingeschränkt, keine Website-Performance wie WP.
---
# 3. Performance-Bewertung
| System | Performance für 1000 Besucher/Tag |
|--------|-----------------------------------|
| WordPress (mit CDN) | ⭐⭐⭐⭐⭐ |
| Odoo.sh Website | ⭐⭐ |
| Odoo self-hosted Website über DSL | ⭐ (Upload-Limit!) |
WordPress ist **um Größenordnungen** besser für Public Traffic.
---
# 4. Sicherheitsbewertung
| System | Risiko bei Public Exposure |
|--------|----------------------------|
| WordPress | gering (gefiltert, gehärtet, cached) |
| Odoo Website | hoch (direkter Zugriff auf Business-Daten) |
| Odoo API | gering (nur ausgewählte Daten, stark begrenzt) |
Odoo sollte **nicht** öffentlich zugänglich sein, außer über **stark eingeschränkte REST API**.
---
# 5. Kostenbewertung
| Option | Monatliche Kosten | Skalierbarkeit |
|--------|-------------------|----------------|
| WordPress gehostet | 520 € | sehr gut |
| Odoo self-hosted | ~020 € | sehr gut |
| **Odoo.sh** | **ab ~40 € pro Benutzer** | schlecht bei vielen Ehrenamtlichen |
**Odoo.sh wäre ruinös teuer für ein FabLab.**
---
# 6. Empfohlene Zielarchitektur
```
Internet
|
| 1000 Besucher/Tag
v
WordPress Website (öffentlich)
|
| REST-API (lesend!)
v
Odoo API Gateway (open_workshop_api)
|
| internal-only
v
Odoo Backend (POS, Maintenance, Trainings, Events)
```
**Vorteile:**
- Odoo bleibt geschützt im LAN oder VPN
- Kein DSL-Upload-Limit problematisch → API ist sehr leichtgewichtig
- WordPress ist ultraschnell & SEO-stark
- Odoo liefert Daten dynamisch an WP (z.B. Maschinenliste, Kurse)
- Keine Benutzerkosten für Ehrenamtliche
---
# 7. Fazit
Die beste Lösung für HobbyHimmel besteht aus einer Kombination:
# 🟩 **WordPress für öffentliche Website**
# 🟩 **Odoo (self-hosted) für Verwaltung & Prozesse**
# 🟩 **API-Modul für WordPress-Anbindung**
# 🟥 **Keine Odoo Website für Öffentlichkeit**
# 🟥 **Kein Odoo.sh wegen hoher Lizenzkosten**
Diese Architektur ist:
- Sicher
- Schnell
- Zukunftssicher
- Kosteneffizient
- Flexibel
- Perfekt für ein FabLab mit vielen Ehrenamtlichen
---
# 8. Nächste Schritte
Wenn gewünscht, kann ich liefern:
### ✔ Architekturdiagramm (grafisch)
### ✔ open_workshop_api Modul als Odoo-Modul-Skeleton
### ✔ WordPress-Shortcodes oder Plugin
### ✔ Sicherheitsempfehlungen (CORS, Token, Firewalls)
### ✔ Optimierungskonzept für den späteren Betrieb

View File

@ -0,0 +1,323 @@
# Projektplan: MQTT-basierte IoT-Events in Odoo 18 Community (Simulation-first)
Stand: 2026-01-10
Ziel: **Odoo-18-Community (self-hosted)** soll **Geräte-Events** (Timer/Maschinenlaufzeit, Waage, Zustandswechsel) über **MQTT** aufnehmen und in Odoo als **saubere, nachvollziehbare Sessions/Events** verarbeiten.
Wichtig: **Hardware wird zunächst vollständig simuliert** (Software-Simulatoren), damit die Odoo-Schnittstelle stabil steht, bevor echte Geräte angebunden werden.
---
## 1. Ziele und Nicht-Ziele
### 1.1 Ziele (MVP)
- Einheitliche **Device-Event-Schnittstelle** in Odoo (REST/Webhook) inkl. Authentifizierung
- **Event-Log** in Odoo (persistente Rohereignisse + Normalisierung)
- **Session-Logik** für Timer/Maschinenlaufzeit (Start/Stop/Heartbeat)
- **Simulation** von:
- Maschinenzustand (running/idle/fault)
- Timer-Events (run_start/run_stop)
- Waage (stable_weight/tare)
- Reproduzierbare Tests (Unit/Integration) und eindeutige Fehlerdiagnostik (Logging)
### 1.2 Nicht-Ziele (für Phase 1)
- Keine Enterprise-IoT-Box, keine Enterprise-Module
- Keine echte Hardware-Treiberentwicklung in Phase 1
- Kein POS-Frontend-Live-Widget (optional erst in späterer Phase)
- Keine Abrechnungslogik/Preisregeln (kann vorbereitet, aber nicht umgesetzt werden)
---
## 2. Zielarchitektur (Simulation-first)
### 2.1 Komponenten
1. **MQTT Broker** (z. B. Mosquitto in Docker)
2. **Device Simulator(s)** (Python/Node)
- veröffentlicht MQTT Topics wie echte Geräte
3. **Gateway/Bridge (Software)**
- abonniert MQTT Topics
- validiert/normalisiert Payload
- sendet Events via HTTPS an Odoo (Webhook)
4. **Odoo Modul** `ows_iot_bridge`
- REST Controller `/ows/iot/event`
- Modelle für Devices, Events, Sessions
- Business-Regeln für Session-Start/Stop/Hysterese (softwareseitig)
5. Optional später: **Realtime-Feed** (WebSocket) für POS/Display
### 2.2 Datenfluss
1. Simulator publiziert MQTT → `hobbyhimmel/machines/<machine_id>/state`
2. Bridge konsumiert MQTT, mappt auf Event-Format
3. Bridge POSTet JSON an Odoo Endpoint
4. Odoo speichert Roh-Event + erzeugt ggf. Session-Updates
---
## 3. Schnittstelle zu Odoo (Kern des Projekts)
### 3.1 Authentifizierung
- Pro Device oder pro Bridge ein **API-Token** (Bearer)
- Header: `Authorization: Bearer <token>`
- Token in Odoo in `ows.iot.device` oder `ir.config_parameter` hinterlegt
- Optional: IP-Allowlist / Rate-Limit (in Reverse Proxy)
### 3.2 Endpoint (REST/Webhook)
- `POST /ows/iot/event`
- Content-Type: `application/json`
- Antwort:
- `200 OK` mit `{ "status": "ok", "event_id": "...", "session_id": "..." }`
- Fehler: `400` (Schema), `401/403` (Auth), `409` (Duplikat), `500` (Server)
### 3.3 Idempotenz / Duplikaterkennung
- Jedes Event enthält eine eindeutige `event_uid`
- Odoo legt Unique-Constraint auf `event_uid` (pro device)
- Wiederholte Events liefern `409 Conflict` oder `200 OK (duplicate=true)` (Designentscheidung)
---
## 4. Ereignis- und Topic-Standard (Versioniert)
### 4.1 MQTT Topics (v1)
- Maschinenzustand:
`hobbyhimmel/machines/<machine_id>/state`
- Maschinenereignisse:
`hobbyhimmel/machines/<machine_id>/event`
- Waage:
`hobbyhimmel/scales/<scale_id>/event`
- Geräte-Status (optional):
`hobbyhimmel/devices/<device_id>/status`
### 4.2 Gemeinsames JSON Event Schema (v1)
Pflichtfelder:
- `schema_version`: `"v1"`
- `event_uid`: UUID/string
- `ts`: ISO-8601 UTC (z. B. `"2026-01-10T12:34:56Z"`)
- `source`: `"simulator" | "device" | "gateway"`
- `device_id`: string
- `entity_type`: `"machine" | "scale" | "sensor"`
- `entity_id`: string (z. B. machine_id)
- `event_type`: string (siehe unten)
- `payload`: object
- `confidence`: `"high" | "medium" | "low"` (für Sensorfusion)
### 4.3 Event-Typen (v1)
**Maschine/Timer**
- `run_start` (Start einer Laufphase)
- `run_stop` (Ende einer Laufphase)
- `heartbeat` (optional, laufend während running)
- `state_changed` (idle/running/fault)
- `fault` (Fehler mit Code/Severity)
**Waage**
- `stable_weight` (stabiler Messwert)
- `weight` (laufend)
- `tare`
- `zero`
- `error`
---
## 5. Odoo Datenmodell (Vorschlag)
### 5.1 `ows.iot.device`
- `name`
- `device_id` (unique)
- `token_hash` (oder Token in separater Tabelle)
- `device_type` (machine/scale/...)
- `active`
- `last_seen`
- `notes`
### 5.2 `ows.iot.event`
- `event_uid` (unique)
- `device_id` (m2o -> device)
- `entity_type`, `entity_id`
- `event_type`
- `timestamp`
- `payload_json` (Text/JSON)
- `confidence`
- `processing_state` (new/processed/error)
- `session_id` (m2o optional)
### 5.3 `ows.machine.session` (Timer-Sessions)
- `machine_id` (Char oder m2o auf bestehendes Maschinenmodell)
- `start_ts`, `stop_ts`
- `duration_s` (computed)
- `state` (running/stopped/aborted)
- `origin` (sensor/manual/sim)
- `confidence_summary`
- `event_ids` (o2m)
> Hinweis: Wenn du bereits `ows.machine` aus deinem open_workshop nutzt, referenziert `machine_id` direkt dieses Modell.
---
## 6. Verarbeitungslogik (Phase 1: minimal, robust)
### 6.1 Session-Automat (State Machine)
- Eingang: Events `run_start`, `run_stop`, optional `heartbeat`
- Regeln:
- `run_start` erstellt neue Session, wenn keine läuft
- `run_start` während laufender Session → nur Log, keine neue Session
- `run_stop` schließt laufende Session
- Timeout-Regel: wenn `heartbeat` ausbleibt (z. B. 10 min) → Session `aborted`
### 6.2 Hysterese (Simulation als Stellvertreter für Sensorik)
In Simulation definierst du:
- Start, wenn „running“ mindestens **2s stabil**
- Stop, wenn „idle“ mindestens **15s stabil**
Diese Parameter als Odoo Systemparameter, z. B.:
- `ows_iot.start_debounce_s`
- `ows_iot.stop_debounce_s`
---
## 7. Simulation (Software statt Hardware)
### 7.1 Device Simulator: Maschine
- Konfigurierbar:
- Muster: random, fixed schedule, manuell per CLI
- Zustände: idle/running/fault
- Optional: „power_w“ und „vibration“ als Felder im Payload
- Publiziert MQTT in realistischen Intervallen
### 7.2 Device Simulator: Waage
- Modi:
- stream weight (mehrfach pro Sekunde)
- stable_weight nur auf „stabil“
- tare/zero Events per CLI
### 7.3 Bridge Simulator (MQTT → Odoo)
- Abonniert alle relevanten Topics
- Validiert Schema v1
- POSTet Events an Odoo
- Retry-Queue (lokal) bei Odoo-Ausfall
- Metriken/Logs:
- gesendete Events, Fehlerquoten, Latenz
---
## 8. Milestones & Deliverables
### M0 Repo/Grundgerüst (0.51 Tag)
**Deliverables**
- Git-Repo Struktur
- Docker Compose: mosquitto + simulator + bridge
- Odoo Modul Skeleton `ows_iot_bridge`
### M1 Odoo Endpoint & Modelle (12 Tage)
**Deliverables**
- `/ows/iot/event` Controller inkl. Token-Auth
- Modelle `ows.iot.device`, `ows.iot.event`
- Admin UI: Geräte anlegen, Token setzen, letzte Events anzeigen
### M2 Session-Engine (12 Tage)
**Deliverables**
- Modell `ows.machine.session`
- Event → Session Zuordnung
- Timeout/Abbruch-Logik
- Parameter für Debounce/Timeout
### M3 Simulatoren & End-to-End Test (12 Tage)
**Deliverables**
- Machine Simulator + Scale Simulator
- Bridge mit Retry-Queue
- End-to-End: Simulator → MQTT → Bridge → Odoo → Session entsteht
### M4 Qualität & Betrieb (1 Tag)
**Deliverables**
- Logging-Konzept (Odoo + Bridge)
- Tests (Unit: Controller/Auth, Integration: Session Engine)
- Doku: Event-Schema v1, Topics, Beispielpayloads
### Optional M5 POS/Anzeige (später)
- Realtime Anzeige im POS oder auf Display
- Live-Weight in POS
---
## 9. Testplan (Simulation-first)
### 9.1 Unit Tests (Odoo)
- Auth: gültiger Token → 200
- ungültig/fehlend → 401/403
- Schema-Validation → 400
- Idempotenz: duplicate `event_uid` → 409 oder duplicate-flag
### 9.2 Integration Tests
- Sequenz: start → heartbeat → stop → Session duration plausibel
- stop ohne start → kein Crash, Event loggt Fehlerzustand
- Timeout: start → keine heartbeat → Session aborted
### 9.3 Last-/Stabilitätstest (Simulator)
- 20 Maschinen, je 1 Event/s, 1h Lauf
- Ziel: Odoo bleibt stabil, Event-Insert performant, Queue läuft nicht über
---
## 10. Betriebs- und Sicherheitskonzept
- Token-Rotation möglich (neues Token, altes deaktivieren)
- Reverse Proxy:
- HTTPS
- Rate limiting auf `/ows/iot/event`
- optional Basic WAF Regeln
- Payload-Größenlimit (z. B. 1664 KB)
- Bridge persistiert Retry-Queue auf Disk
---
## 11. Offene Entscheidungen (später, nicht blocker für MVP)
- Event-Consumer in Odoo vs. Bridge-only Webhook (empfohlen: Webhook)
- Genaues Mapping zu bestehenden open_workshop Modellen (`ows.machine`, Nutzer/RFID)
- Abrechnung: Preisregeln, Rundungen, POS-Integration
- Realtime: Odoo Bus vs. eigener WebSocket Service
---
## 12. Nächste Schritte (konkret)
1. `ows_iot_bridge` Modul: Endpoint + Device/Event Modelle implementieren
2. Docker Compose: mosquitto + bridge + simulator bereitstellen
3. Simulatoren produzieren v1-Events; Bridge sendet an Odoo
4. Session-Engine anschließen und End-to-End testen
---
## Anhang A: Beispiel-Event (Maschine run_start)
```json
{
"schema_version": "v1",
"event_uid": "c2a7d6f1-7d8d-4a63-9a7f-4e6d7b0d9e2a",
"ts": "2026-01-10T12:34:56Z",
"source": "simulator",
"device_id": "esp32-fraser-01",
"entity_type": "machine",
"entity_id": "formatkreissaege",
"event_type": "run_start",
"confidence": "high",
"payload": {
"power_w": 820,
"vibration": 0.73,
"reason": "power_threshold"
}
}
```
## Anhang B: Beispiel-Event (Waage stable_weight)
```json
{
"schema_version": "v1",
"event_uid": "b6d0a2c5-9b1f-4a0b-8b19-7f2e1b8f3d11",
"ts": "2026-01-10T12:40:12Z",
"source": "simulator",
"device_id": "scale-sim-01",
"entity_type": "scale",
"entity_id": "waage-01",
"event_type": "stable_weight",
"confidence": "high",
"payload": {
"weight_g": 1532.4,
"unit": "g",
"stable_ms": 1200
}
}
```

View File

@ -0,0 +1,538 @@
# 0. Migration: open_workshop → open_workshop_base ✅ ABGESCHLOSSEN
**Status: ERLEDIGT (08.12.2025)**
Die Migration wurde erfolgreich durchgeführt:
- ✅ SQL-Migration: Modul umbenannt in Datenbank
- ✅ Pre-Migration: maintenance.equipment Integration vorbereitet
- ✅ Post-Migration: 23 Maschinen zu maintenance.equipment migriert
- ✅ _inherits Pattern implementiert (ows.machine → maintenance.equipment)
- ✅ Automatische Migration in CI/CD Pipeline integriert
- ✅ UX verbessert: Equipment wird automatisch erstellt
- ✅ Location readonly und auto-sync von area
- ✅ Menü umbenannt zu "Ausrüstung"
**Technische Details:**
- Alte Felder entfernt: code, description, storage_location, purchase_price, purchase_date
- Delegation an maintenance.equipment: name, serial_no, location, cost, effective_date
- JSONB für mehrsprachige Namen (de_DE, en_US)
- Area → Location Synchronisation automatisch
---
# Open Workshop FEATURE PLAN
## Vollständige Modularisierung + WordPress REST API Integration (API = Pflicht)
Dieses Dokument ist die **finale, vollständig korrigierte Version** des Feature-Plans.
Es kombiniert alle Inhalte der vorherigen Dokumente, **konsolidiert, bereinigt und vereinheitlicht**,
und stellt klar:
# ⭐ Die API ist ein **Pflichtbestandteil** der finalen Architektur.
Das Dokument ist **eigenständig** und enthält alles, was ein Entwickler oder KI-Agent benötigt,
um das gesamte Open-Workshop-System korrekt modularisiert aufzubauen.
---
# 1. Gesamtziel
Das Projekt *Open Workshop* soll in eine moderne, klare und skalierbare Architektur überführt werden:
- **Odoo (intern)** als Verwaltungs-Backend für Maschinen, Einweisungen, POS, Maintenance, Events.
- **WordPress (extern)** als öffentliche Website mit hoher Performance und SEO.
- **REST API (Pflicht!)** als Kommunikationsschicht zwischen beiden Systemen.
Damit entsteht:
```
WordPress (öffentlich)
| REST API (nur lesend)
Odoo (intern, geschützt)
```
Diese Architektur vermeidet:
- Performance-Probleme durch DSL-Uplink
- Sicherheitsrisiken von Odoo im Internet
- Hohe Kosten für Odoo.sh Benutzerlizenzen
---
# 2. Aktuelle Modulstruktur (Stand: 08.12.2025)
```
open_workshop/
├── open_workshop/ # ✅ Alt-Modul (installable=False, Kompatibilität)
├── open_workshop_base/ # ✅ FERTIG Backend, _inherits maintenance.equipment
├── open_workshop_pos/ # ✅ FERTIG POS-Integration (JS, XML, UI)
├── open_workshop_dokuwiki/ # ⏳ IN ENTWICKLUNG DokuWiki-Integration
└── open_workshop_api/ # 💤 OPTIONAL REST API (zurückgestellt)
```
**Entfernt:** open_workshop_maintenance (verworfen - Funktionalität direkt in open_workshop_base integriert)
---
# 3. Modul: open_workshop_base ✅ FERTIG
**Status: PRODUKTIV (18.0.1.0.4)**
Enthält:
- ✅ `ows.machine` mit _inherits zu `maintenance.equipment` (delegiert alle Felder von maintenance.equipment transparent an ows.machine)
- ✅ `ows.machine.area` (Bereiche mit JSONB-Namen)
- ✅ `ows.machine.product` (Nutzungsprodukte)
- ✅ `ows.machine.training` (Einweisungsprodukte)
- ✅ `ows.machine.access` (Zugriffsfreigaben)
- ✅ Automatische Equipment-Erstellung bei Maschinenanlage
- ✅ Area → Location Synchronisation
- ✅ Sicherheitsregeln (ir.model.access)
- ✅ Backend-UI: Form, Tree, Search/Filter
- ✅ Smart Button zu Equipment-Details
- ✅ Integration mit OCA maintenance Modulen
**Abhängigkeiten:**
- base, account, hr, product, sale, contacts, **maintenance**
**Maintenance Integration:**
- Statt separatem Modul: Direkte Integration via _inherits
- Equipment-Felder: name, serial_no, location, cost, effective_date
- OWS-Felder: category, area_id, product_ids, training_ids
---
# 4. Modul: open_workshop_pos ✅ FERTIG
**Status: PRODUKTIV**
Vollständig separiertes POS-Modul mit:
### JS-Module:
- ✅ ows_machine_access_list.js
- ✅ ows_pos_customer_sidebar.js
- ✅ ows_pos_sidebar.js
- ✅ ows_product_screen_template_patch.js
### XML-Templates:
- ✅ QWeb Templates für POS-UI
- ✅ Maschinenfreigaben-Widget
- ✅ Customer Sidebar mit Zugriffsstatus
### Assets:
```json
'point_of_sale.assets': [
'open_workshop_pos/static/src/js/**/*.js',
'open_workshop_pos/static/src/xml/**/*.xml',
'open_workshop_pos/static/src/css/**/*.css'
]
```
**Abhängigkeiten:**
- open_workshop_base
- point_of_sale
**Integration:**
- Zeigt Maschinenzugriffe im POS
- Filterung nach Bereichen
- Live-Status der Freigaben
---
# 5. Modul: open_workshop_dokuwiki ⏳ IN ENTWICKLUNG
**Status: IN ENTWICKLUNG (Branch: feature/dokuwiki-integration)**
Dieses Modul integriert **DokuWiki** als Dokumentationssystem für Equipment.
## 5.1 Ziele
- Automatische Wiki-Seiten für jedes Equipment
- **Invertierte Include-Architektur**:
- Odoo generiert geschützte Hauptseite mit Equipment-Daten
- Hauptseite inkludiert User-Dokumentation via Include Plugin
- User editieren separate `:doku` Unterseite
- **Klare Datentrennung**:
- Odoo = Master für strukturierte Daten (Hauptseite, read-only für User)
- User = Master für Freitext-Dokumentation (`:doku` Unterseite, editierbar)
- **Generisches ACL-System**: Eine Regel für alle Equipment
- Versionierung durch DokuWiki eingebaut
## 5.2 Architektur
```
Odoo (maintenance.equipment)
XML-RPC Client
DokuWiki API (wiki.putPage)
werkstatt:ausruestung:bereich:maschinenname
```
## 5.3 DokuWiki-Seitenstruktur
**Zwei-Seiten-System pro Equipment:**
```
werkstatt:ausruestung:holzwerkstatt:formatkreissaege ← Hauptseite (Odoo generiert)
werkstatt:ausruestung:holzwerkstatt:formatkreissaege:doku ← Doku-Seite (User editieren)
werkstatt:ausruestung:lasercutter:epilog_fusion_m2 ← Hauptseite
werkstatt:ausruestung:lasercutter:epilog_fusion_m2:doku ← Doku-Seite
```
**Namespace-Regeln:**
- **Hauptnamespace**: `werkstatt:ausruestung:`
- **Hauptseite**: `werkstatt:ausruestung:bereich:maschinenname`
- Bereich: ows_area_id (normalisiert, lowercase)
- Maschinenname: Equipment name (normalisiert, ohne Sonderzeichen)
- **Komplett Odoo-generiert**, User können nicht editieren
- **Doku-Seite**: `werkstatt:ausruestung:bereich:maschinenname:doku`
- **User editieren hier frei** (Anleitungen, Tipps, Bilder)
- Wird via Include in Hauptseite eingebunden
- User können weitere Unterseiten anlegen (`:doku:bilder`, `:doku:videos`)
## 5.4 Hauptseiten-Template (Odoo-generiert)
Odoo erstellt die komplette Hauptseite inklusive Include für User-Dokumentation:
```wiki
====== Formatkreissäge ======
===== Grunddaten =====
* **Seriennummer:** FKS-2024-001
* **Bereich:** [[werkstatt:ausruestung:holzwerkstatt|Holzwerkstatt]]
* **Kategorie:** 🔴 Kategorie 3 (Einweisung erforderlich)
* **Standort:** Schrank A, Regal 2
* **Hersteller:** Bosch
===== Sicherheit =====
* **Einweisungspflichtig:** Ja
* **Nutzungsprodukte:**
* Holzwerkstatt Nutzung (5€/Tag)
* **Einweisungsprodukte:**
* Einweisung Formatkreissäge (einmalig 25€)
===== Wartung =====
* **Letzte Wartung:** 01.12.2025
* **Nächste Wartung:** 01.06.2026
* **Wartungshistorie:** [[odoo:maintenance:request:42|Alle Wartungsaufträge]]
===== Dokumentation & Anleitungen =====
{{page>.:formatkreissaege:doku&noheader}}
[[.:formatkreissaege:doku|✏️ Dokumentation bearbeiten]]
```
**User-Doku-Seite** (`:doku`, User editieren hier):
```wiki
==== Bedienung ====
1. Hauptschalter einschalten
2. Sägeblatt-Drehzahl einstellen
3. Anschlag positionieren
...
==== Tipps & Tricks ====
- Bei Hartholz: Vorschub langsamer
- Sägeblatt nach 50h wechseln
==== Bilder ====
{{.:doku:bild1.jpg?300}}
```
## 5.5 Technische Umsetzung
**Python-Bibliothek:**
- `dokuwiki` (Python XML-RPC Client für DokuWiki)
- Installation: `pip install dokuwiki`
**API-Methoden:**
```python
# DokuWiki XML-RPC API
wiki.putPage(page_id, content, summary, minor) # Seite erstellen/aktualisieren
wiki.getPage(page_id) # Seite lesen
wiki.getAllPages() # Alle Seiten auflisten
```
**Odoo-Integration:**
- Neues Model: `ows.dokuwiki.config` (DokuWiki-URL, Credentials)
- Methode auf `maintenance.equipment`: `sync_to_dokuwiki()`
- Automated Action: Bei Equipment-Änderung → Wiki aktualisieren
- Smart Button: "Wiki öffnen" → Link zur DokuWiki-Seite
**Sync-Algorithmus (vereinfacht!):**
```python
def sync_to_dokuwiki(self):
"""Generiert Hauptseite mit Include für User-Doku"""
# 1. Generiere Hauptseite komplett (Odoo hat volle Kontrolle)
content = self._generate_equipment_page()
# 2. Füge Include für User-Doku hinzu
wiki_id = self._get_normalized_name()
content += "\n\n===== Dokumentation & Anleitungen =====\n"
content += f"{{{{page>.:{{wiki_id}}:doku&noheader}}}}\n\n"
content += f"[[.:{{wiki_id}}:doku|✏️ Dokumentation bearbeiten]]\n"
# 3. Schreibe Hauptseite (überschreibt komplett)
main_page = f"werkstatt:ausruestung:{self.ows_area_id.wiki_name}:{wiki_id}"
dokuwiki_client.putPage(main_page, content, "Odoo Auto-Sync")
# 4. Erstelle leere Doku-Seite falls nicht vorhanden
doku_page = f"{main_page}:doku"
if not dokuwiki_client.getPage(doku_page):
initial_doku = "==== Bedienung ====\n\n==== Tipps & Tricks ====\n"
dokuwiki_client.putPage(doku_page, initial_doku, "Initial")
def _generate_equipment_page(self):
"""Generiert komplette Hauptseite mit Equipment-Daten"""
return f"""====== {self.name} ======
===== Grunddaten =====
* **Seriennummer:** {self.serial_no or 'N/A'}
* **Bereich:** [[werkstatt:ausruestung:{self.ows_area_id.wiki_name}|{self.ows_area_id.name}]]
* **Kategorie:** {self._get_category_icon()} {self._get_category_label()}
* **Standort:** {self.location or 'N/A'}
* **Hersteller:** {self.partner_id.name or 'N/A'}
===== Sicherheit =====
* **Einweisungspflichtig:** {self._is_training_required()}
* **Nutzungsprodukte:**
{self._format_product_list(self.ows_product_ids)}
* **Einweisungsprodukte:**
{self._format_product_list(self.ows_training_ids)}
===== Wartung =====
* **Letzte Wartung:** {self.last_maintenance_date or 'N/A'}
* **Nächste Wartung:** {self.next_action_date or 'N/A'}
"""
```
**Vorteile dieser Architektur:**
- ✅ Keine Sync-Marker nötig (Hauptseite wird komplett überschrieben)
- ✅ User können Odoo-Daten nicht versehentlich löschen
- ✅ User-Content ist komplett geschützt (separate Seite)
- ✅ Include funktioniert transparent (User sehen alles auf einer Seite)
- ✅ Wartungsfreies ACL-System
## 5.6 ACL-System (Generisch & Wartungsfrei)
**Phase 1: Nur für Odoo sichtbar (Initial-Setup)**
```
# Komplett gesperrt für alle außer Odoo
werkstatt:ausruestung:* @odoo 8 # Voller Zugriff
werkstatt:ausruestung:* @ALL 0 # Kein Zugriff
```
**Phase 2: Werkstatt-Betreiber erhalten Zugriff (später)**
```
# User-Doku-Seiten editierbar (spezifischere Regel zuerst!)
werkstatt:ausruestung:*:doku @werkstatt 2 # Editieren erlaubt
werkstatt:ausruestung:*:doku:* @werkstatt 2 # Auch Unterseiten (Bilder, Videos, etc.)
# Hauptseiten nur lesen
werkstatt:ausruestung:* @werkstatt 1 # Nur Lesezugriff
werkstatt:ausruestung:* @ALL 1 # Alle können lesen
# Odoo hat vollen Zugriff überall
werkstatt:ausruestung:* @odoo 8 # Voller Zugriff
werkstatt:ausruestung:*:doku @odoo 8 # Auch auf Doku-Seiten (für Initial-Erstellung)
**Wie es funktioniert:**
| Seite | User @werkstatt | User @odoo | Ergebnis |
|-------|-----------------|------------|----------|
| `werkstatt:ausruestung:holzwerkstatt:formatkreissaege` | Matched: `werkstatt:ausruestung:*` → 1 | Matched: `werkstatt:ausruestung:*` → 8 | User: Lesen, Odoo: Schreiben |
| `werkstatt:ausruestung:holzwerkstatt:formatkreissaege:doku` | Matched: `werkstatt:ausruestung:*:doku` → 2 | Matched: `werkstatt:ausruestung:*:doku` → 8 | User: Editieren, Odoo: Voll |
- `16` = Admin (alle Rechte)
**Vorteile:**
- ✅ **Komplett generisch**: Gilt automatisch für alle Equipment
- ✅ **Wartungsfrei**: Kein manuelles ACL-Setup pro Equipment
- ✅ **Phasenweise Freischaltung**: Erst Odoo-Only, dann schrittweise für Werkstatt
- ✅ **Selbsterklärend**: User sehen sofort wo sie editieren können
- ✅ **Skalierbar**: Funktioniert auch für 1000+ Equipment-Seiten
| `ausruestung:holzwerkstatt:formatkreissaege` | Matched: `ausruestung:*` → 1 | Matched: `ausruestung:*` → 8 | User: Lesen, Odoo: Schreiben |
| `ausruestung:holzwerkstatt:formatkreissaege:doku` | Matched: `ausruestung:*:doku` → 2 | Matched: `ausruestung:*:doku` → 8 | User: Editieren, Odoo: Voll |
**Vorteile:**
- ✅ **Komplett generisch**: Gilt automatisch für alle Equipment
- ✅ **Wartungsfrei**: Kein manuelles ACL-Setup pro Equipment
- ✅ **Selbsterklärend**: User sehen sofort wo sie editieren können
- ✅ **Skalierbar**: Funktioniert auch für 1000+ Equipment-Seiten
**Odoo-Seite:**
- Credentials in `ir.config_parameter`:
- `dokuwiki.url` (z.B. `https://wiki.hobbyhimmel.de`)
- `dokuwiki.user` (z.B. `odoo`)
- `dokuwiki.password` (verschlüsselt gespeichert)
- XML-RPC über HTTPS
- Logging aller Wiki-Operationen in `mail.message`
## 5.7 Vorteile DokuWiki
**Leichtgewichtig** File-based, keine separate Datenbank
**Versionierung** Eingebautes History-System
**Wiki-Syntax** Perfekt für strukturierte Dokumentation
**ACL-System** Granulare Berechtigungen
**Suchfunktion** Volltext-Suche eingebaut
**Plugins** Erweiterbar (Markdown, Galleries, etc.)
**Open Source** Keine Lizenzkosten
---
# 6. Modul: open_workshop_api ⏳ GEPLANT
**Status: ZURÜCKGESTELLT (DokuWiki hat Priorität)**
REST API für externe Systeme (falls später WordPress/App-Integration gewünscht).
## 6.1 Potenzielle Endpunkte
```
GET /api/v1/machines
GET /api/v1/machine/<id>
GET /api/v1/areas
```
**Hinweis:** Mit DokuWiki kann die öffentliche Dokumentation direkt über das Wiki erfolgen.
Eine separate REST API ist optional und wird nur bei Bedarf implementiert.
## 6.1 Warum DokuWiki statt WordPress?
- **Einfacher**: Keine separate Datenbank, file-based
- **Wiki-Syntax**: Perfekt für technische Dokumentation
- **Versionierung**: Eingebautes History-System
- **ACL**: Feinere Berechtigungskontrolle
- **Leichtgewichtig**: Weniger Overhead als WordPress
- **Integration**: XML-RPC API für bidirektionale Sync
## 6.2 Zukunft: WordPress optional
Falls später gewünscht, kann WordPress **zusätzlich** die öffentliche Maschinenliste anzeigen:
- DokuWiki für **Dokumentation** (intern/extern lesbar)
- WordPress für **Präsentation** (extern mit Bildern, SEO)
- Beide Systeme greifen auf Odoo-Daten zu
Aktuell hat DokuWiki-Integration **Priorität**.
---
# 7. Finaler Architektur-Plan
```
Internet
|
DokuWiki (Dokumentation)
WordPress (optional: Präsentation)
|
XML-RPC / REST API
|
----------------------------
| Odoo Backend (LAN/VPN)
| open_workshop_dokuwiki
| maintenance.equipment
----------------------------
POS, Benutzer, Einweisungen
```
**Fokus:** Equipment-Dokumentation über DokuWiki, WordPress später optional.
---
# 8. Sicherheit
**DokuWiki ACL:**
- Namespace `ausruestung:*` lesbar für alle (@ALL = 1)
- Namespace `ausruestung:*` schreibbar nur für Odoo (@odoo = 8)
- Manuelle Edits durch Admins möglich
**Odoo:**
- DokuWiki-Credentials in ir.config_parameter
- XML-RPC über HTTPS
- Logging aller Wiki-Operationen
- Backup-System für Wiki-Dateien
**Optional (REST API):**
- Reverse Proxy sperrt alle Odoo-URLs außer `/api/v1/*`
- HTTPS erzwingen
- Rate-Limit + Firewall
- Token-Auth
---
# 9. Vorteile dieser Architektur
**DokuWiki für Dokumentation** Wiki-Syntax perfekt für Anleitungen
**Versionierung eingebaut** History für alle Änderungen
**Odoo bleibt sicher** hinter Firewall
**Keine Benutzerkosten** alle Ehrenamtlichen können intern mitarbeiten
**Modular, wartbar, zukunftssicher**
**Intelligente Sync** Nur strukturierte Daten werden überschrieben, Freitext bleibt erhalten
**Öffentlich lesbar** Anleitungen für alle verfügbar
**WordPress optional** Kann später für Marketing/SEO ergänzt werden
---
# 10. Implementierungsstand (13.12.2025)
| Schritt | Status | Details |
|---------|--------|---------|
| 1. open_workshop_base | ✅ **FERTIG** | Version 18.0.1.0.4, produktiv |
| 2. open_workshop_pos | ✅ **FERTIG** | POS-Integration komplett |
| 3. ~~open_workshop_maintenance~~ | ❌ **VERWORFEN** | Direkt in Base integriert |
| 4. Maintenance Integration | ✅ **FERTIG** | _inherits Pattern implementiert |
| 5. Equipment-View Integration | ✅ **FERTIG** | Related fields, Menu-Migration |
| 6. Migration Workflow | ✅ **FERTIG** | SQL + Python, CI/CD integriert |
| 7. open_workshop_dokuwiki | ⏳ **IN ENTWICKLUNG** | Branch: feature/dokuwiki-integration |
| 8. open_workshop_api | 💤 **OPTIONAL** | Zurückgestellt, bei Bedarf |
---
# 11. Nächste Schritte
1. **open_workshop_dokuwiki** entwickeln
- DokuWiki XML-RPC Client implementieren
- Template-System für Equipment-Seiten
- Sync-Mechanismus (Odoo → Wiki)
- Smart Button "Wiki öffnen"
- ACL-Konfiguration dokumentieren
2. **DokuWiki aufsetzen**
- Installation auf Server
- Namespace `ausruestung:` anlegen
- ACL konfigurieren (@odoo Gruppe)
- XML-RPC API aktivieren
3. **Testing**
- Equipment-Seiten automatisch generieren
- Sync bei Änderungen testen
- ACL-Rechte validieren
- Performance testen
4. **Optional: WordPress Plugin**
- Falls öffentliche Präsentation gewünscht
- REST API dann implementieren
- Caching-Layer hinzufügen
---
# 12. Endfazit
Diese Architektur vereint das Beste aus beiden Welten:
- ✅ **Technisch korrekt** _inherits Pattern statt separatem Modul
- ✅ **Performant** Maintenance.equipment als Single Source of Truth
- ✅ **Dokumentiert** DokuWiki für strukturierte Anleitungen
- ✅ **Versioniert** History-System eingebaut
- ✅ **Öffentlich zugänglich** Wiki lesbar für alle
- ✅ **Kostenoptimiert** Keine zusätzlichen Lizenzen
- ✅ **Langfristig erweiterbar** Modularer Aufbau
- ✅ **Produktiv im Einsatz** Migration erfolgreich abgeschlossen
**DokuWiki-Integration ist der nächste logische Schritt** für bessere Equipment-Dokumentation.
**Letztes Update: 13.12.2025**

View File

@ -0,0 +1,142 @@
# Empfohlene Modulstruktur für Open_Workshop + öffentliches Website-Modul
## 🎯 Ziel
Du möchtest:
1. Ein **öffentliches Website-Modul**, das Maschineninformationen aus dem Maintenance-Modul anzeigt.
2. Dein gesamtes `open_workshop`-Repository sinnvoll modularisieren.
Diese Antwort beschreibt die optimale Struktur und die Gründe dafür.
---
# ✅ Öffentliches Modul ist sinnvoll
Du möchtest:
- Maschinen anzeigen (Maintenance)
- Zustand sichtbar machen
- Bilder & PDFs anzeigen
- ohne Login (auth="public")
➡️ Dafür ist ein eigenes Modul **open_workshop_website** ideal.
Dieses Website-Modul sollte *nur Anzeige* machen, keine Logik verwalten.
---
# ⭐ Empfohlene Modulstruktur (Best Practice)
```
open_workshop/
├── open_workshop_pos/ # POS-Integration, Einweisungen, Freigaben
├── open_workshop_maintenance/ # Verbindung zu maintenance.equipment
│ # z. B. Modelle, Felder, Extensions
└── open_workshop_website/ # Öffentliche Darstellung, QR-Codes, Website
```
---
# 🧩 Gründe für diese modulare Struktur
## 1⃣ Trennung nach funktionalen Bereichen
Odoo trennt:
- POS
- Maintenance
- Website
Du solltest dasselbe tun.
So bleibt alles klar, logisch und update-sicher.
---
## 2⃣ Bessere Wartbarkeit
Wenn Odoo 19/20 Änderungen bringt:
- POS ändert sich → nur `open_workshop_pos`
- Maintenance ändert sich → nur `open_workshop_maintenance`
- Website ändert sich → nur `open_workshop_website`
Ein großes Sammelmodul wäre schwer zu warten.
---
## 3⃣ Nutzer können auswählen, was sie brauchen
Beispiel:
Ein Kunde will nur Maschinen + Website, aber kein POS.
Dann installiert er:
- `open_workshop_maintenance`
- `open_workshop_website`
🔧 Ohne unnötige POS-Abhängigkeit.
---
## 4⃣ Klare Modulabhängigkeiten
### `open_workshop_pos`
- depends: `point_of_sale`
### `open_workshop_maintenance`
- depends: `maintenance`
### `open_workshop_website`
- depends: `website`
- optional depends: `open_workshop_maintenance`
Alles sauber getrennt.
---
## 5⃣ Erweiterbarkeit bleibt einfach
Dein Projekt wächst schnell:
- QR-Codes
- Maschinenstatus
- API
- Dashboards
- Rollen mit Einweisungssichtbarkeit
Wenn alles in EINEM Modul wäre → unübersichtlich
Wenn modular → perfekt strukturiert
---
# ❌ Warum alles in *einem einzigen Modul* schlecht wäre
- Mischmasch aus POS, Website und Maintenance-Code
- schwerer zu debuggen
- schlechtere Wiederverwendbarkeit
- mehr Merge-Konflikte
- Odoo selbst macht das nie so
---
# 🎉 Fazit
Die modulare Struktur ist optimal und entspricht OCA/Odoo-Best-Practices:
| Modul | Zweck |
|-------|--------|
| **open_workshop_pos** | Einweisung, Freigaben, POS GUI |
| **open_workshop_maintenance** | Maschinenmodellierung, Maintenance-Anbindung |
| **open_workshop_website** | öffentliche Darstellung, QR-Codes |
---
# 📦 Optional: Nächster Schritt
Ich kann dir komplette Modul-Gerüste erstellen:
- Manifest-Dateien
- Controller
- Views
- Templates
- QR-Code-Integration
- Demo-Daten
Sag einfach Bescheid:
👉 *„Bitte erstelle mir das Grundgerüst.“*

View File

@ -0,0 +1,161 @@
# Maschinen- und Geräteverwaltung im FabLab mit Odoo Maintenance + Open_Workshop
## 🎯 Ausgangssituation
In der Werkstatt existieren viele verschiedene Maschinen und Geräte:
- stationär
- mobil
- elektrisch
- mechanisch
- verschiedene Sicherheits- und Einweisungsanforderungen
Der aktuelle Zustand, Bilder und Bedienungsanleitungen sind unstrukturiert im Wiki gespeichert.
Das Ziel ist:
- eine zentrale, strukturierte Verwaltung in **Odoo**
- Anzeige des Maschinenzustands
- Zugriff für Nutzer auf Bedienungsanleitungen
- ohne Backend-Zugang
- am besten über Website/Portal + QR-Codes
---
## 💡 Die perfekte Lösung: Maintenance-Modul + Open_Workshop + Website
Die optimale Architektur besteht aus drei Komponenten:
1. **Maintenance-Modul**
→ Zentrale Verwaltung aller Maschinen/Devices
2. **Open_Workshop-Modul**
→ Freigaben, Einweisungen, POS-Integration
3. **Website-/Portal-Modul (Custom)**
→ Anzeige für Nutzer: Maschine, Zustand, Anleitung, QR-Codes
Diese Kombination ist robust, klar strukturiert und update-sicher.
---
# ✅ Warum das Maintenance-Modul ideal ist
Das Modell `maintenance.equipment` bietet bereits alles, was du brauchst:
| Feld | Nutzen |
|------|--------|
| `name` | Maschinenname |
| `category_id` | Maschinenbereich |
| `maintenance_state` | Betriebszustand |
| `note` | Beschreibung |
| `image_1920` | Maschinenbild |
| `message_attachment_count` | PDFs & Dateien |
| Anhänge | Bedienungsanleitungen |
Diese Felder machen das Maintenance-Modul zur perfekten **Source of Truth**.
---
# 🧩 Wie du die Daten Nutzern sichtbar machst
Nicht das Backend öffnen.
Nicht `website=True` setzen.
Sondern:
### ✔ Eigener Website-/Portal-Controller
Beispiele:
### Maschinenliste
```
/workshop/machines
```
### Maschinendetailansicht
```
/workshop/machine/<id>
```
Dort sieht der Nutzer:
- Bild
- Betriebszustand
- Kategorie
- Beschreibung
- Bedienungsanleitung (PDF-Download)
- optional: Sicherheitsinfos
- optional: Einweisungsstatus (aus Open_Workshop)
Alles **read-only**, ohne Backend.
---
# 🔒 Zugriffsvarianten
Du entscheidest selbst:
## **Option A: Öffentlich**
- Keine Anmeldung nötig
- Zustand und Anleitung für alle sichtbar
- Ideal für Tablets im FabLab oder QR-Codes an Maschinen
## **Option B: Portal-Zugang**
- Nutzer müssen sich einloggen
- Anleitungen nur für registrierte Mitglieder sichtbar
## **Option C: Hybrid**
- Zustand öffentlich
- Anleitungen nur für eingeloggte Benutzer mit Einweisung
Diese Variante passt besonders gut zu deinem Open_Workshop-Modell.
---
# 🧰 Integration mit Open_Workshop
Die ideale Struktur ist:
```
maintenance.equipment ←→ ows.machine ←→ ows.machine.access
```
Das bedeutet:
- Maintenance = technische Daten
- Open_Workshop = Einweisungsprozesse
- Website = Darstellung
---
# 📲 QR-Codes an den Maschinen
Odoo kann automatisch QR-Codes generieren.
Du platzierst auf jeder Maschine einen QR-Code, z. B.:
```
/workshop/machine/42
```
Der Nutzer scannt ihn und sieht:
- Bild
- Zustand
- Anleitung
- ggf. "Einweisung vorhanden" / "Keine Einweisung"
---
# 🚀 Modularer Vorschlag für deine Architektur
### **1. Maintenance-Modul**
Zentrale Maschinenverwaltung
### **2. Open_Workshop-Modul**
Einweisung, Freigaben, POS
### **3. Custom Website-Modul**
- Maschinenliste
- Detailseiten
- PDF-Downloads
- Einweisungsstatus
- optional QR-Code-Automatik

View File

@ -1,5 +0,0 @@
from . import models
from . import controllers
from . import post_init_hook
# damit run_migration sichtbar ist:
run_migration = post_init_hook.run_migration

View File

@ -1,38 +0,0 @@
{
'name': 'POS Open Workshop',
'license': 'AGPL-3',
'version': '13.0.1.0.0',
'summary': 'Erstellt Maschinenfreigaben basierend auf POS-Einweisungsprodukten',
'depends': ['base','product','sale','contacts','point_of_sale'],
'author': 'matthias.lotz',
'category': 'Point of Sale',
'data': [
'security/ir.model.access.csv',
'views/machine_product_training_views.xml',
'views/menu_views.xml',
'views/machine_area_views.xml',
'views/machine_views.xml',
'views/res_partner_view.xml',
'views/assets.xml',
'data/data.xml',
],
'qweb': [
'static/src/xml/ows_briefing_details.xml',
'static/src/xml/ows_briefing_details_edit.xml',
'static/src/xml/ows_pos_order_selector.xml',
'static/src/xml/ows_machine_sidebar.xml',
'static/src/xml/ows_pos_machine_access_view.xml',
],
'installable': True,
'assets': {
'point_of_sale.assets': [
'static/src/js/machine_access_sidebar.js',
'static/src/css/pos.css',
],
},
'post_init_hook': 'run_migration',
'description': """
Diese App erstellt Maschinenfreigaben basierend auf POS-Einweisungsprodukten.
Die App ist für den Einsatz in der Odoo-Version 13.0 konzipiert.
""",
}

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from odoo import api, SUPERUSER_ID
from . import models
from . import report
from . import wizard
# TODO: Generate Sequence For each company for Equipment
def pre_init_hook(env):
company_ids = env['res.company'].search([])
for company_id in company_ids:
sequence_id = env['ir.sequence'].search(
[('name', '=', 'Equipment Company Sequence'), ('company_id', '=', company_id.id)])
if not sequence_id:
env['ir.sequence'].create({
'name': 'Equipment Company Sequence',
'prefix': company_id.id,
'padding': 5,
'number_increment': 1,
'company_id': company_id.id
})

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
###############################################################################
#
# Aspire Softserv Pvt. Ltd.
# Copyright (C) Aspire Softserv Pvt. Ltd.(<https://aspiresoftserv.com>).
#
###############################################################################
{
"name": "QR Code on Equipment",
'category': '',
"summary": "Add QR Code on equipment for managing equipment.",
"version": "18.0.0.1.0",
"license": "AGPL-3",
"price": 00.00,
'description': """
The Equipment Management Module generates unique QR codes for each asset, offering instant details and direct Odoo profile access for seamless management.
""",
"author": "Aspire Softserv Pvt. Ltd",
"website": "https://aspiresoftserv.com",
"depends": ['account','maintenance'],
"external_dependencies": {
'python': ['qrcode']
},
"data": [
'views/maintenance_equipment.xml',
'security/ir.model.access.csv',
'report/custom_qrcode.xml',
'wizard/equipment_label_layout_views.xml',
],
'pre_init_hook': 'pre_init_hook',
"application": True,
"installable": True,
"maintainer": "Aspire Softserv Pvt. Ltd",
"support": "odoo@aspiresoftserv.com",
'images': ['static/description/banner.gif'],
}

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import maintenance_equipment
from . import res_company

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from odoo import models, fields
class MaintenanceEquipment(models.Model):
_inherit = 'maintenance.equipment'
qr_code = fields.Binary("QR Code", attachment=True)
comp_serial_no = fields.Char("Inventory Serial No", tracking=True)
serial_no = fields.Char('Mfg. Serial Number', copy=False)
def action_print_qrcode_layout(self):
action = self.env['ir.actions.act_window']._for_xml_id('aspl_equipment_qrcode_generator.action_open_label_layout_equipment')
action['context'] = {'default_equipment_ids': self.ids}
return action
def generate_serial_no(self):
for equipment_id in self:
if not equipment_id.comp_serial_no:
company_id = equipment_id.company_id.id
sequence_id = self.env['ir.sequence'].search(
[('name', '=', 'Equipment Company Sequence'), ('company_id', '=', company_id)])
if sequence_id:
data = sequence_id._next()
equipment_id.write({
'comp_serial_no': data
})

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from odoo import models, api
class ResCompany(models.Model):
_inherit = 'res.company'
@api.model
def create(self, vals):
result = super(ResCompany, self).create(vals)
sequence_id = self.env['ir.sequence'].search(
[('name', '=', 'Equipment Company Sequence'), ('company_id', '=', result.id)])
if not sequence_id:
self.env['ir.sequence'].create({
'name': 'Equipment Company Sequence',
'prefix': result.id,
'padding': 5,
'number_increment': 1,
'company_id': result.id
})
return result

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import custom_qrcode_generator

View File

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="report_equipment_simple_label2x7">
<t t-set="qrcode_size" t-value="'height:14mm'"/>
<t t-set="table_style" t-value="'width:97mm;height:37.1mm;margin:inherit;' + table_style"/>
<td t-att-style="make_invisible and 'visibility:hidden;'" >
<div class="o_label_full" t-att-style="table_style">
<div class="o_label_name">
<strong t-field="equipment.name"/>
</div>
<div class="o_label_data">
<div class="text-center o_label_right_column">
<t t-if="equipment.qr_code">
<img t-att-src="'data:image/png;base64,' + equipment.qr_code.decode('utf-8')" style="width: 130px;margin-top: -40px;"/>
</t>
</div>
<div class="text-left" style="line-height:normal;word-wrap: break-word;">
<span class="text-nowrap" t-field="equipment.serial_no"/>
<div class="o_label_extra_data">
<span t-field="equipment.comp_serial_no"/>
</div>
<t t-if="equipment.warranty_date">
<strong t-field="equipment.warranty_date"/>
</t>
</div>
<div class="o_label_clear"></div>
</div>
</div>
</td>
</template>
<template id="report_equipment_simple_label4x7">
<t t-set="barcode_size" t-value="'width:80px;'"/>
<t t-set="table_style" t-value="'width:47mm;height:37.1mm;margin:inherit;' + table_style"/>
<td t-att-style="make_invisible and 'visibility:hidden;'" >
<div class="o_label_full" t-att-style="table_style">
<div class="o_label_name">
<strong t-field="equipment.name"/>
</div>
<div class= "text-center o_label_right_column">
<t t-if="equipment.qr_code">
<img t-att-src="'data:image/png;base64,' + equipment.qr_code.decode('utf-8')" style="width:95px;padding:0px;margin-top:-10px"/>
</t>
</div>
<div class="text-left o_label_left_column" style="line-height:normal;word-wrap: break-word;">
<div class="o_label_data">
<strong t-field="equipment.serial_no"/>
<span t-field="equipment.comp_serial_no"/>
<t t-if="equipment.warranty_date">
<strong t-field="equipment.warranty_date"/>
</t>
</div>
</div>
</div>
</td>
</template>
<template id="report_equipment_simple_label2x5">
<t t-set="barcode_size" t-value="'width:38mm;height:14mm;margin-top:50px;'"/>
<t t-set="table_style"
t-value="'width:97mm;height:50mm;font-size: 12px;border: 2px solid black;table-layout: fixed;'"/>
<td>
<table t-att-style="table_style">
<tr>
<td style="width:25%;">Name</td>
<td style="width:5%">:</td>
<td colspan="2" style="width:70%;word-wrap: break-word;">
<span t-field="equipment.name"/>
</td>
</tr>
<tr>
<td style="width:25%">Model</td>
<td style="width:5%">:</td>
<td style="width:35%;word-wrap: break-word;">
<span t-field="equipment.model"/>
</td>
<td rowspan="5" style="width:35%">
<t t-if="equipment.qr_code">
<img t-att-src="'data:image/png;base64,' + equipment.qr_code.decode('utf-8')"
style="width:30mm;height:30mm;"/>
</t>
</td>
</tr>
<tr>
<td style="width:25%">Mfg Serial</td>
<td style="width:5%">:</td>
<td style="width:35%;font-size:10px;word-wrap: break-word;">
<span t-field="equipment.serial_no"/>
</td>
</tr>
<tr>
<td style="width:25%">Serial</td>
<td style="width:5%">:</td>
<td style="width:35%;word-wrap: break-word;">
<span t-field="equipment.comp_serial_no"/>
</td>
</tr>
<tr>
<td style="width:25%">Warranty Date</td>
<td style="width:5%">:</td>
<td style="width:35%;word-wrap: break-word;">
<span t-field="equipment.warranty_date"/>
</td>
</tr>
<tr>
<td style="width:25%"></td>
<td style="width:5%"></td>
<td style="width:35%;word-wrap: break-word;"></td>
</tr>
</table>
</td>
</template>
<template id="report_quipmentlabel">
<t t-call="web.html_container">
<t t-if="columns and rows">
<t t-if="columns == 2 and rows == 7">
<t t-set="padding_page" t-value="'padding: 14mm 3mm'"/>
<t t-set="report_to_call" t-value="'aspl_equipment_qrcode_generator.report_equipment_simple_label2x7'"/>
</t>
<t t-if="columns == 4 and rows == 7">
<t t-set="padding_page" t-value="'padding: 14mm 3mm'"/>
<t t-set="report_to_call" t-value="'aspl_equipment_qrcode_generator.report_equipment_simple_label4x7'"/>
</t>
<t t-if="columns == 2 and rows == 5">
<t t-set="padding_page" t-value="'padding: 14mm 3mm'"/>
<t t-set="report_to_call" t-value="'aspl_equipment_qrcode_generator.report_equipment_simple_label2x5'"/>
</t>
<t t-foreach="range(page_numbers)" t-as="page">
<div class="o_label_sheet" t-att-style="padding_page">
<table class="my-0 table table-sm table-borderless">
<t t-foreach="range(rows)" t-as="row">
<tr>
<t t-foreach="range(columns)" t-as="column">
<t t-if="equipment_data">
<t t-set="current_data" t-value="equipment_data.popitem()"/>
<t t-set="equipment" t-value="current_data[0]"/>
<t t-set="table_style" t-value="'border: 1px solid black'"/>
<t t-call="{{report_to_call}}"/>
</t>
</t>
</tr>
</t>
</table>
</div>
</t>
</t>
</t>
</template>
<template id="maintenance_quip">
<t t-call="web.basic_layout">
<div class="page">
<t t-call="aspl_equipment_qrcode_generator.report_quipmentlabel">
<t t-set="products" t-value="products"/>
</t>
</div>
</t>
</template>
<record id="paperformat_label_sheet_qrcode" model="report.paperformat">
<field name="name">A4 Label Sheet</field>
<field name="default" eval="True"/>
<field name="format">A4</field>
<field name="page_height">0</field>
<field name="page_width">0</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="disable_shrinking" eval="True"/>
<field name="dpi">96</field>
</record>
<record id="report_equipment_label" model="ir.actions.report">
<field name="name">Equipment QR-code (PDF)</field>
<field name="model">maintenance.equipment</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">aspl_equipment_qrcode_generator.maintenance_quip</field>
<field name="report_file">aspl_equipment_qrcode_generator.maintenance_quip</field>
<field name="paperformat_id" ref="aspl_equipment_qrcode_generator.paperformat_label_sheet_qrcode"/>
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<field name="binding_model_id" eval="False"/>
<field name="binding_type">report</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class ReportProductTemplateLabel(models.AbstractModel):
_name = 'report.aspl_equipment_qrcode_generator.maintenance_quip'
_description = 'Equipment QR-code Report'
def _get_report_values(self, docids, data=None):
"""
QR-Code-Generierung erfolgt im Wizard (equipment_label_layout.py).
Dieser Report rendert nur die bereits generierten QR-Codes.
"""
if not data:
return {}
equipment_label_layout_id = self.env['equipment.label.layout'].browse(data.get('equipment_label_layout_id'))
equipment_dict = {}
for equipment in equipment_label_layout_id.equipment_ids:
equipment_dict[equipment] = 1
page_numbers = (len(equipment_label_layout_id.equipment_ids) - 1) // (
equipment_label_layout_id.rows * equipment_label_layout_id.columns
) + 1
return {
'rows': equipment_label_layout_id.rows,
'columns': equipment_label_layout_id.columns,
'page_numbers': page_numbers,
'equipment_data': equipment_dict
}

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_equipment_label_layout,access.equipment_label_layout,model_equipment_label_layout,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_equipment_label_layout access.equipment_label_layout model_equipment_label_layout 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

View File

@ -0,0 +1,165 @@
<section class="oe_container" style="border-left:1px solid grey;border-right :1px solid grey;font-family: Urbanist ,'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;" >
<div class="oe_row oe_spaced">
<div style="display:flex;margin-top:5rem;padding : 0rem 5rem;">
<div><img src="./images/logo.png" style="width:200px;"/></div>
<div style="width: 100%;text-align: end;"><a href="https://hrms.aspiresoftserv.com/contactus" class="btn" target="_blank" style="background-color:#011D45;color:white;border-radius:5px;"><i class="fa fa-envelope" style="margin-right:0.5rem"></i>Request A Demo</a></div>
</div>
</div>
<div class="oe_row oe_spaced" style="margin-top:5rem;text-align:center;width:100%;">
<h3 style="color:#011D45;">Euipment Qr-code</h3>
<h6 style="color:#011D45;width: 50%;margin: auto;text-align: left;">
The Equipment Management Module streamlines the intricate process of equipment management by generating unique QR codes for each asset. Scanning these QR codes instantly provides comprehensive details about the equipment. Additionally, the QR code features a direct link to the equipment's profile in Odoo, facilitating seamless management and updates.</h6>
<br/>
<h4 style="color:#011D45;width: 50%;margin: auto;text-align: left;margin-bottom:2px;">Prerequisite:-</h4>
<h6 style="color:#011D45;width: 50%;margin: auto;text-align: left;">
pip install qrcode==6.1
</h6>
</div>
<div class="oe_row oe_spaced" style="display:flex;margin-top:3rem;">
<div style="width:750px;margin: auto;">
<img src="./banner.gif" style="width:100%">
</div>
</div>
<div class="oe_row oe_spaced" style="display:flex;">
<h3 style="color:#011D45;margin: auto;">Screenshots</h3>
</div>
<div class="oe_row oe_spaced" style="display:flex;">
<div style="margin: auto;">
<div style="width:800px;padding: 2rem;">
<div style="width:100%;text-align:left;">
<h4 style="color:#011D45;">Sequence Configuration</h4>
<h6 style="color:#011D45;">Once you install the module, It will automatically create maintenance sequence for available company.</h6>
</div>
<div style="width:80%;margin:auto;margin-top: 1rem;">
<img src="./screenshots/1_sequence.png" style="width:100%;">
</div>
</div>
<div style="width:800px;background-color:#F4F6F6;padding: 2rem;">
<div style="width:100%;text-align:left;">
<h4 style="color:#011D45;">Serial number Generation</h4>
<h6 style=" color:#011D45;">In the equipment, you'll find a "Generate Serial Number" button. When you click this button, it automatically creates a serial number based on the company's predefined sequence, which is set up when the module is installed (check above screenshot related to sequence configuration).
</h6>
</div>
<div style="width:80%;margin:auto;margin-top: 1rem;">
<img src="./screenshots/2_equipment_screen.png" style="width:100%">
</div>
</div>
<div style="width:800px;padding: 2rem;">
<div style="width:100%;text-align:left;">
<h4 style="color:#011D45;">Print QR-Code View</h4>
<h6 style="color:#011D45;">In the equipment tree view, When you select an item, It will display a "QR Code" button.</h6>
</div>
<div style="width:80%;margin:auto;margin-top: 1rem;">
<img src="./screenshots/3_equipment_tree.png" style="width:100%;">
</div>
</div>
<div style="width:800px;background-color:#F4F6F6;padding: 2rem;">
<div style="width:100%;text-align:left;">
<h4 style="color:#011D45;">QR Code Size Options</h4>
<h6 style="color:#011D45;">The module will display all available options for QR code sizes, allowing you to choose the appropriate dimensions for generating your QR codes.</h6>
</div>
<div style="width:80%;margin:auto;margin-top: 1rem;">
<img src="./screenshots/4_qrcode_size_selection.png" style="width:100%;">
</div>
</div>
</div>
</div>
<div class="oe_row oe_spaced" style="display:flex;margin-top:3rem;">
<h3 style="color:#011D45;margin: auto;">Suggested Apps</h3>
</div>
<div id="slides" class="row carousel slide mt64 mb32" style="width:800px;margin:auto;" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" style="min-height: 0px;">
<div class="row no-lg-gutters">
<div class="col-6 col-sm-3 text-center">
<a class="d-block"
href="https://apps.odoo.com/apps/modules/15.0/aspl_project_timesheet_activity/"
style="text-decoration: none;" target="_blank">
<img alt="Project Timesheet Activity" src="./images/aspl_project_timesheet_activity.png" style="width:60%;">
<div class="card-body text-center p-0 mt-3 mb-3 mb-lg-0">
<h6 class="card-text m-0" style="font-size: 16px; color:#011D45;font-weight: 600">
Project Timesheet<br>Activity</h6>
</div>
</a>
</div>
<div class="col-6 col-sm-3 text-center">
<a class="d-block"
href="https://apps.odoo.com/apps/modules/15.0/aspl_save_view_to_favourite/"
style="text-decoration: none;" target="_blank">
<img alt="Project Timesheet Activity" src="./images/aspl_save_view_to_favourite.png" style="width:60%;">
<div class="card-body text-center p-0 mt-3 mb-3 mb-lg-0">
<h6 class="card-text m-0" style="font-size: 16px; color:#011D45;font-weight: 600">
Project Timesheet<br>Activity</h6>
</div>
</a>
</div>
<div class="col-6 col-sm-3 text-center">
<a class="d-block"
href="https://apps.odoo.com/apps/modules/15.0/aspl_select_multi_company/"
style="text-decoration: none;" target="_blank">
<img alt="Select Multi Company" src="./images/aspl_select_multi_company.png" style="width:60%;">
<div class="card-body text-center p-0 mt-3 mb-3 mb-lg-0">
<h6 class="card-text m-0" style="font-size: 16px; color:#011D45;font-weight: 600">
Select Multi<br>Company</h6>
</div>
</a>
</div>
<div class="col-6 col-sm-3 text-center">
<a class="d-block"
href="https://apps.odoo.com/apps/modules/15.0/aspl_project_task_milestone/"
style="text-decoration: none;" target="_blank">
<img alt="Project Task Milestone" src="./images/project_task_milestone.png" style="width:60%;">
<div class="card-body text-center p-0 mt-3 mb-3 mb-lg-0">
<h6 class="card-text m-0" style="font-size: 16px;color:#011D45; font-weight: 600">
Project Task <br>Milestone</h6>
</div>
</a>
</div>
<div class="col-6 col-sm-3 text-center">
<a class="d-block"
href="https://apps.odoo.com/apps/modules/15.0/aspl_equipment_qrcode_generator/"
style="text-decoration: none;" target="_blank">
<img alt="Qr Code" src="./icon.png" style="width:60%;">
<div class="card-body text-center p-0 mt-3 mb-3 mb-lg-0">
<h6 class="card-text m-0" style="font-size: 16px;color:#011D45; font-weight: 600">
Qr Code</h6>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="oe_row oe_spaced" style="display:flex;margin-top:1rem;">
<div style="width:750px;margin: auto;">
<img src="./images/service_banner.png" style="width:100%">
</div>
</div>
<div class="oe_row oe_spaced" style="display:flex;margin-top:4rem;">
<div style="width:800px;height:140px;margin: auto;">
<img src="./images/bg_image.png" width="100%;">
<div style="margin-left: 2rem;margin-top:-110px;display: flex;">
<div>
<h5 style="color:white;">Free Support</h5>
<p style="color:white;">We will provide free support for any issues,queries and bug fixing<br/>upto
90 days from the date of purchase of this application.</p>
</div>
<div style="margin-left: auto;margin-right: 2rem;margin-top: 2rem;">
<div style="background-color:white;color:#011D45;border-radius:5px;padding: 4px;width:205px;text-align:center;"><a
href="https://hrms.aspiresoftserv.com/contactus" style="text-decoration:none;color:#011D45;"
target="_blank">Request Free Support</a></div>
</div>
</div>
</div>
</div>
<div class="oe_row oe_spaced" style="display:flex;margin-top:-35px;">
<div style="width:600px;display:flex;margin: auto;">
<div style="display: flex;"><i class="fa fa-envelope" style="margin-right:0.4rem;margin-top:0.2rem;color:#D81A58;"></i><a href="mailto:sales@aspiresoftserv.com" style="text-decoration:none;color:#D81A58;">sales@aspiresoftserv.com</a></div>
<div style="display: flex;margin: 0 3rem;"><i class="fa fa-skype" style="margin-right:0.4rem;color:#D81A58;margin-top:0.2rem;"></i><a href="skype:aspire.software?chat" style="text-decoration:none;color:#D81A58;">aspire.software</a></div>
<div style="display: flex;"><i class="fa fa-phone" style="margin-right:0.4rem;color:#D81A58;margin-top:0.2rem;"></i><span style="text-decoration:none;color:#D81A58;">+916351895006</span></div>
</div>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_extend_equipment_tree" model="ir.ui.view">
<field name="name">maintenance.equipment.tree.inherit</field>
<field name="model">maintenance.equipment</field>
<field name="priority" eval="16"/>
<field name="inherit_id" ref="maintenance.hr_equipment_view_tree"/>
<field name="arch" type="xml">
<xpath expr="//list" position="inside">
<header>
<button string="Print QR-code" type="object" name="action_print_qrcode_layout"/>
</header>
</xpath>
</field>
</record>
<record id="view_extend_equipment_form" model="ir.ui.view">
<field name="name">maintenance.equipment.form.inherit</field>
<field name="model">maintenance.equipment</field>
<field name="priority" eval="16"/>
<field name="inherit_id" ref="maintenance.hr_equipment_view_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='product_information']" position="inside">
<group>
<field name="comp_serial_no"/>
</group>
</xpath>
<xpath expr="//sheet" position="before">
<header>
<button string="Generate Serial Number" type="object" name="generate_serial_no" class="oe_highlight"/>
</header>
</xpath>
</field>
</record>
<record id="generate_serial_no_action" model="ir.actions.server">
<field name="name">Generate Serial Number</field>
<field name="model_id" ref="model_maintenance_equipment"/>
<field name="binding_model_id" ref="model_maintenance_equipment"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">action = records.generate_serial_no()</field>
</record>
<record id="generate_qrcode_no_action" model="ir.actions.server">
<field name="name">Print QR-Code</field>
<field name="model_id" ref="model_maintenance_equipment"/>
<field name="binding_model_id" ref="model_maintenance_equipment"/>
<field name="binding_view_types">form</field>
<field name="state">code</field>
<field name="code">action = records.action_print_qrcode_layout()</field>
</record>
</odoo>

View File

@ -0,0 +1,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import equipment_label_layout

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
class EquipmentLabelLayout(models.TransientModel):
_name = 'equipment.label.layout'
_description = 'Choose the sheet layout to print the labels'
print_format = fields.Selection([
('2x5', '2 x 5'),
('2x7', '2 x 7'),
('4x7', '4 x 7')], string="Format", default='2x5', required=True)
equipment_ids = fields.Many2many('maintenance.equipment')
rows = fields.Integer(compute='_compute_dimensions')
columns = fields.Integer(compute='_compute_dimensions')
@api.model
def default_get(self, fields_list):
"""Override to properly set equipment_ids from context"""
res = super().default_get(fields_list)
if self.env.context.get('active_ids'):
res['equipment_ids'] = [(6, 0, self.env.context.get('active_ids', []))]
elif self.env.context.get('default_equipment_ids'):
res['equipment_ids'] = [(6, 0, self.env.context.get('default_equipment_ids', []))]
return res
@api.depends('print_format')
def _compute_dimensions(self):
for wizard in self:
if 'x' in wizard.print_format:
columns, rows = wizard.print_format.split('x')[:2]
wizard.columns = int(columns)
wizard.rows = int(rows)
else:
wizard.columns, wizard.rows = 1, 1
def process_label(self):
# Generiere QR-Codes für alle Equipment VOR dem Report
self._generate_qr_codes()
xml_id = 'aspl_equipment_qrcode_generator.report_equipment_label'
data = {
'equipment_label_layout_id': self.id
}
# report_action benötigt die Equipment IDs als docids
return self.env.ref(xml_id).report_action(self.equipment_ids.ids, data=data)
def _generate_qr_codes(self):
"""Generiert QR-Codes für alle ausgewählten Equipment"""
import base64
from io import BytesIO
import qrcode
# Hole die base_url für die Equipment-Links
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
menu_id = self.env.ref('maintenance.menu_equipment_form').sudo().id
action_id = self.env.ref('maintenance.hr_equipment_action').sudo().id
for equipment in self.equipment_ids:
# Extrahiere Namen aus JSONB falls nötig
equipment_name = equipment.name
if isinstance(equipment_name, dict):
equipment_name = equipment_name.get('de_DE') or equipment_name.get('en_US') or str(equipment_name)
category_name = equipment.category_id.name if equipment.category_id else ""
if isinstance(category_name, dict):
category_name = category_name.get('de_DE') or category_name.get('en_US') or str(category_name)
# Erstelle Equipment-Link
equipment_link = f"{base_url}/web#id={equipment.id}&menu_id={menu_id}&action={action_id}&model=maintenance.equipment&view_type=form"
# Erstelle Equipment-Details für QR-Code
qr_data = f"Name: {equipment_name}\n"
qr_data += f"Model: {equipment.model or ''}\n"
qr_data += f"Mfg serial no: {equipment.serial_no or ''}\n"
qr_data += f"Warranty Exp. Date: {equipment.warranty_date or ''}\n"
qr_data += f"Category: {category_name}\n\n"
qr_data += equipment_link
# Generiere QR-Code
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=20,
border=4,
)
qr.add_data(qr_data)
qr.make(fit=True)
img = qr.make_image()
temp = BytesIO()
img.save(temp, format="PNG")
qr_image = base64.b64encode(temp.getvalue())
# Speichere QR-Code im Equipment
equipment.write({'qr_code': qr_image})

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="equipment_label_layout_form" model="ir.ui.view">
<field name="name">equipment.label.layout.form</field>
<field name="model">equipment.label.layout</field>
<field name="mode">primary</field>
<field name="arch" type="xml">
<form>
<group>
<field name="equipment_ids" invisible="1"/>
<group>
<field name="print_format" widget="radio"/>
</group>
</group>
<footer>
<button name="process_label" string="Confirm" type="object" class="btn-primary"/>
<button string="Discard" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_open_label_layout_equipment" model="ir.actions.act_window">
<field name="name">Choose Labels Layout</field>
<field name="res_model">equipment.label.layout</field>
<field name="view_ids"
eval="[(5, 0, 0),
(0, 0, {'view_mode': 'form', 'view_id': ref('equipment_label_layout_form')})]" />
<field name="target">new</field>
</record>
</odoo>

View File

@ -1,51 +0,0 @@
id,name,street,zip,city,phone,email,company_type,customer_rank,supplier_rank
res_partner_demo_1, AAAA Max Mustermann,Musterstraße 1,,,,,person,15,0
res_partner_demo_2, Benjamin Winter,,,,,,person,1,0
res_partner_demo_3, Martin Berthelon,Fabrikstr. 3,73728,Esslingen,,martin.berthelon@hotmail.fr,person,15,0
res_partner_demo_4,Aaron Christ,Hohewartstraße 46,70469,Stuttgart,,christ.aaron@web.de,person,14,0
res_partner_demo_5,Aaron Dörr,Riegeläckerstr. 60,71229,Leonberg,,aaron_doerr@web.de,person,33,0
res_partner_demo_6,Aaron Gale,Chopinstr. 20,70195,Stuttgart,015172165290,aarongale1@live.com,person,4,0
res_partner_demo_7,Aaron Zimmermann,Heinrichstr. 15,38106 ,Braunschweig,016091647469,,person,1,0
res_partner_demo_8,Abalrahman Alsadi,Bachstr. 29,70563,Stuttgart,,abdulrahman.m.saadi@gmail.com,person,1,0
res_partner_demo_9,Abdullah Zengin,Engelbertstr. 124,70499,Stuttgart,,,person,3,0
res_partner_demo_10,Abdussamed Korkmaz,Bertha-von-Suttner-Straße 1,74366,Kirchheim Am Neckar,,korkmaz.abdussamed@gmail.com,person,1,0
res_partner_demo_11,Achim Brendle,Oberwiesenstraße 45,70619,Stuttgart,7114797505,achim.brendle@web.de,person,2,0
res_partner_demo_12,Achim Jatkowski,Hummelstr. 38,70569,Stuttgart,017621512316,achim.jatkowski@gmail.com,person,1,0
res_partner_demo_13,Achim Jung,Kurt Tucholsky Str. 6,71254,Ditzingen,07156174013,acjung@web.de,person,1,0
res_partner_demo_14,Achim Kelbel,Vivaldiweg 6,70195,Stuttgart,,a.kelbel@t-online.de,person,2,0
res_partner_demo_15,Achim Kramer,Reinsburger 172,70197,Stuttgart,,achim@zibra.de,person,1,0
res_partner_demo_16,Adalbert Zeisl,Bachstr. 20,71364,Winnenden,07195-2092884,betz1000@gmx.de,person,2,0
res_partner_demo_17,Adalina Schäfer,Sancenbacherstr. 26,74538,Rosengarten,015778855550,lina_max_schaefer@gmx.de,person,1,0
res_partner_demo_18,Adam Riegel,Marabustr. 35 / 84,70378,Stuttgart,0711 532082,,person,1,0
res_partner_demo_19,Adam Swais,Obertürkheimerstr. 54,73733,Esslingen,,adamswais@web.de,person,1,0
res_partner_demo_20,Adela Spulber,Obere Bismarck Str. 97,70197,Stuttgart,,,person,1,0
res_partner_demo_21,Adem Uzun,Liesel-Bach-Str. 54,71034,Böblingen,015251690873,adem.uzun2@gmail.com,person,1,0
res_partner_demo_22,Adnan Djekic,Vesoulerstr. 33,70839,Gerlingen,01724227468,adnandjekic@alice-dsl.net,person,1,0
res_partner_demo_23,Adrian Berres,Bärgstadter Str. 90,63928,Gehenbühl,,a.berres@gmx.de,person,1,0
res_partner_demo_24,Adrian Lanksweirt,Heidestraße 6,70469,Stuttgart,,adrian.lanksweirt@gmail.com,person,1,0
res_partner_demo_25,Adrian Popov,Hallerstr. 42,90419,Nürnberg,+4915114305751,adrinuernberg@gmail.com,person,2,0
res_partner_demo_26,Agnes Krettek,Seyfferstr. 62,70187,Stuttgart,,agneskrettek@gmail.com,person,1,0
res_partner_demo_27,Ahmad Taijan,Rümelinstr 69,70191,Stuttgart,,,person,2,0
res_partner_demo_28,Aileen Becker,Eichendorffstr. 4,73630,Remshalden,015780645637,aileen.becker@gmx.de,person,87,0
res_partner_demo_29,Ailey Simpson,Eierstraße 44 A,70199,Stuttgart,,aileywsimpson@gmail.com,person,1,0
res_partner_demo_30,Akira Mitsu,Fritz-Ulrich-Weg 5,70567,Stuttgart,,mitsuakira0914@gmail.com,person,5,0
res_partner_demo_31,Aksel Özdemir,Rotebühlstraße 53,70178,Stuttgart,,aksel.oezdemir@gmx.de,person,2,0
res_partner_demo_32,Albert Ebenbichler,Am Backhaus 9,73666,Boltmannsweiler,01726101655,info@albert-ebenbichler.com,person,1,0
res_partner_demo_33,Albert Kaupp,Waldäckerstr. 10,70435,Stuttgart,0711 8263232,albert.kaupp@online.de,person,2,0
res_partner_demo_34,Albrecht Barth,Klopstockstr. 39,70193,Stuttgart,,albrecht.barth@web.de,person,3,0
res_partner_demo_35,Albrecht Schlayer,Im Netzbrunnen 17,70825,K-Münchingen,,aws1308@gmail.com,person,1,0
res_partner_demo_36,Alec Dobler,Kräherwald 251,70193,Stuttgart,,,person,1,0
res_partner_demo_37,Alejandro Cano Perez,Burgstallstraße 66,70199,Stuttgart,,cano.perez@gmx.de,person,2,0
res_partner_demo_38,Alejandro Rodriguez,Im Hirschwinkel 1,76297,Stutensee,015771409317,ralexei95@yahoo.de,person,1,0
res_partner_demo_39,Alejandro Zarza Aguado,Reinsburgstr. 152,70197,Stuttgart,017628401435,11alex96@gmail.com,person,1,0
res_partner_demo_40,Aleksandar Vasić,Lothringer Str. 5,70435,Stuttgart,,aleksvasic@web.de,person,3,0
res_partner_demo_41,Alen Minasyan,Kastanienallee 41/1,71638,Ludwigsburg,,bidilik@gmx.de,person,1,0
res_partner_demo_42,Alex Olenberg,Theodor-Rottschildstr. 25,73760,Stuttgart,,,person,26,0
res_partner_demo_43,Alex Schaut,Braunenbergweg 9,70806,Kornwestheim,07154 16530,aschaut@gmx.de,person,3,0
res_partner_demo_44,Alexander Adloff,Charlottenstraße 2,74074,Heilbronn,,alexadloff@gmx.de,person,3,0
res_partner_demo_45,Alexander Bauer,Im Himmel 20,70569,Stuttgart,071172237601,ab.312@icloud.com,person,1,0
res_partner_demo_46,Alexander Blendl,Neckarstr. 8,70736,Fellbach,,blendl.alex@gmail.com,person,4,0
res_partner_demo_47,Alexander Borshov,Schellingstraße 24,71277,Rutesheim,,aborshov@gmail.com,person,1,0
res_partner_demo_48,Alexander Bosch,Osterwiesenstr. 37,70794,Filderstadt,,bosch-alexander@web.de,person,1,0
res_partner_demo_49,Alexander Braig,Holzgrund Str. 25,70806,Kornwestheim,,a.braig84@gmx.de,person,17,0
res_partner_demo_50,Alexander Carolus,Kornbergstr. 23,70176,Stuttgart,,alexander.carolus,person,1,0
1 id name street zip city phone email company_type customer_rank supplier_rank
2 res_partner_demo_1 AAAA Max Mustermann Musterstraße 1 person 15 0
3 res_partner_demo_2 Benjamin Winter person 1 0
4 res_partner_demo_3 Martin Berthelon Fabrikstr. 3 73728 Esslingen martin.berthelon@hotmail.fr person 15 0
5 res_partner_demo_4 Aaron Christ Hohewartstraße 46 70469 Stuttgart christ.aaron@web.de person 14 0
6 res_partner_demo_5 Aaron Dörr Riegeläckerstr. 60 71229 Leonberg aaron_doerr@web.de person 33 0
7 res_partner_demo_6 Aaron Gale Chopinstr. 20 70195 Stuttgart 015172165290 aarongale1@live.com person 4 0
8 res_partner_demo_7 Aaron Zimmermann Heinrichstr. 15 38106 Braunschweig 016091647469 person 1 0
9 res_partner_demo_8 Abalrahman Alsadi Bachstr. 29 70563 Stuttgart abdulrahman.m.saadi@gmail.com person 1 0
10 res_partner_demo_9 Abdullah Zengin Engelbertstr. 124 70499 Stuttgart person 3 0
11 res_partner_demo_10 Abdussamed Korkmaz Bertha-von-Suttner-Straße 1 74366 Kirchheim Am Neckar korkmaz.abdussamed@gmail.com person 1 0
12 res_partner_demo_11 Achim Brendle Oberwiesenstraße 45 70619 Stuttgart 7114797505 achim.brendle@web.de person 2 0
13 res_partner_demo_12 Achim Jatkowski Hummelstr. 38 70569 Stuttgart 017621512316 achim.jatkowski@gmail.com person 1 0
14 res_partner_demo_13 Achim Jung Kurt Tucholsky Str. 6 71254 Ditzingen 07156174013 acjung@web.de person 1 0
15 res_partner_demo_14 Achim Kelbel Vivaldiweg 6 70195 Stuttgart a.kelbel@t-online.de person 2 0
16 res_partner_demo_15 Achim Kramer Reinsburger 172 70197 Stuttgart achim@zibra.de person 1 0
17 res_partner_demo_16 Adalbert Zeisl Bachstr. 20 71364 Winnenden 07195-2092884 betz1000@gmx.de person 2 0
18 res_partner_demo_17 Adalina Schäfer Sancenbacherstr. 26 74538 Rosengarten 015778855550 lina_max_schaefer@gmx.de person 1 0
19 res_partner_demo_18 Adam Riegel Marabustr. 35 / 84 70378 Stuttgart 0711 532082 person 1 0
20 res_partner_demo_19 Adam Swais Obertürkheimerstr. 54 73733 Esslingen adamswais@web.de person 1 0
21 res_partner_demo_20 Adela Spulber Obere Bismarck Str. 97 70197 Stuttgart person 1 0
22 res_partner_demo_21 Adem Uzun Liesel-Bach-Str. 54 71034 Böblingen 015251690873 adem.uzun2@gmail.com person 1 0
23 res_partner_demo_22 Adnan Djekic Vesoulerstr. 33 70839 Gerlingen 01724227468 adnandjekic@alice-dsl.net person 1 0
24 res_partner_demo_23 Adrian Berres Bärgstadter Str. 90 63928 Gehenbühl a.berres@gmx.de person 1 0
25 res_partner_demo_24 Adrian Lanksweirt Heidestraße 6 70469 Stuttgart adrian.lanksweirt@gmail.com person 1 0
26 res_partner_demo_25 Adrian Popov Hallerstr. 42 90419 Nürnberg +4915114305751 adrinuernberg@gmail.com person 2 0
27 res_partner_demo_26 Agnes Krettek Seyfferstr. 62 70187 Stuttgart agneskrettek@gmail.com person 1 0
28 res_partner_demo_27 Ahmad Taijan Rümelinstr 69 70191 Stuttgart person 2 0
29 res_partner_demo_28 Aileen Becker Eichendorffstr. 4 73630 Remshalden 015780645637 aileen.becker@gmx.de person 87 0
30 res_partner_demo_29 Ailey Simpson Eierstraße 44 A 70199 Stuttgart aileywsimpson@gmail.com person 1 0
31 res_partner_demo_30 Akira Mitsu Fritz-Ulrich-Weg 5 70567 Stuttgart mitsuakira0914@gmail.com person 5 0
32 res_partner_demo_31 Aksel Özdemir Rotebühlstraße 53 70178 Stuttgart aksel.oezdemir@gmx.de person 2 0
33 res_partner_demo_32 Albert Ebenbichler Am Backhaus 9 73666 Boltmannsweiler 01726101655 info@albert-ebenbichler.com person 1 0
34 res_partner_demo_33 Albert Kaupp Waldäckerstr. 10 70435 Stuttgart 0711 8263232 albert.kaupp@online.de person 2 0
35 res_partner_demo_34 Albrecht Barth Klopstockstr. 39 70193 Stuttgart albrecht.barth@web.de person 3 0
36 res_partner_demo_35 Albrecht Schlayer Im Netzbrunnen 17 70825 K-Münchingen aws1308@gmail.com person 1 0
37 res_partner_demo_36 Alec Dobler Kräherwald 251 70193 Stuttgart person 1 0
38 res_partner_demo_37 Alejandro Cano Perez Burgstallstraße 66 70199 Stuttgart cano.perez@gmx.de person 2 0
39 res_partner_demo_38 Alejandro Rodriguez Im Hirschwinkel 1 76297 Stutensee 015771409317 ralexei95@yahoo.de person 1 0
40 res_partner_demo_39 Alejandro Zarza Aguado Reinsburgstr. 152 70197 Stuttgart 017628401435 11alex96@gmail.com person 1 0
41 res_partner_demo_40 Aleksandar Vasić Lothringer Str. 5 70435 Stuttgart aleksvasic@web.de person 3 0
42 res_partner_demo_41 Alen Minasyan Kastanienallee 41/1 71638 Ludwigsburg bidilik@gmx.de person 1 0
43 res_partner_demo_42 Alex Olenberg Theodor-Rottschildstr. 25 73760 Stuttgart person 26 0
44 res_partner_demo_43 Alex Schaut Braunenbergweg 9 70806 Kornwestheim 07154 16530 aschaut@gmx.de person 3 0
45 res_partner_demo_44 Alexander Adloff Charlottenstraße 2 74074 Heilbronn alexadloff@gmx.de person 3 0
46 res_partner_demo_45 Alexander Bauer Im Himmel 20 70569 Stuttgart 071172237601 ab.312@icloud.com person 1 0
47 res_partner_demo_46 Alexander Blendl Neckarstr. 8 70736 Fellbach blendl.alex@gmail.com person 4 0
48 res_partner_demo_47 Alexander Borshov Schellingstraße 24 71277 Rutesheim aborshov@gmail.com person 1 0
49 res_partner_demo_48 Alexander Bosch Osterwiesenstr. 37 70794 Filderstadt bosch-alexander@web.de person 1 0
50 res_partner_demo_49 Alexander Braig Holzgrund Str. 25 70806 Kornwestheim a.braig84@gmx.de person 17 0
51 res_partner_demo_50 Alexander Carolus Kornbergstr. 23 70176 Stuttgart alexander.carolus person 1 0

View File

@ -1,2 +0,0 @@
/opt/odoo/odoo/odoo-bin shell -d hobbyhimmel < /home/odoo/custom_addons/open_workshop/demo/export_partner.py

View File

@ -1,38 +0,0 @@
import csv
import random
# Beispielsweise 50 Kunden mit Namen und E-Mail
partners = env['res.partner'].search(
[('customer_rank', '>', 0), ('is_company', '=', False)],
limit=50
)
with open('/home/odoo/custom_addons/open_workshop/demo/demo_partners.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
'id',
'name',
'street',
'zip',
'city',
'phone',
'email',
'company_type',
'customer_rank',
'supplier_rank'
])
for idx, partner in enumerate(partners, start=1):
partner_id = f'res_partner_demo_{idx}'
writer.writerow([
partner_id,
partner.name or '',
partner.street or '',
partner.zip or '',
partner.city or '',
partner.phone or '',
partner.email or '',
partner.company_type or 'person',
partner.customer_rank,
partner.supplier_rank,
])

View File

@ -1,31 +0,0 @@
# -*- coding: utf-8 -*-
from odoo import SUPERUSER_ID
from odoo.api import Environment
import logging
_logger = logging.getLogger(__name__)
MISSING_PARTNERS = [
6534, 1594, 4700, 6557, 5392, 4960, 5226, 6535, 4666
]
def insert_missing_partners(cr, registry):
env = Environment(cr, SUPERUSER_ID, {})
for partner_id in MISSING_PARTNERS:
cr.execute("""
INSERT INTO res_partner (
id, name, customer_rank, create_uid, create_date, write_uid, write_date
)
VALUES (%s, %s, 1, %s, now(), %s, now())
ON CONFLICT (id) DO NOTHING;
""", (partner_id, f"Fehlender Partner {partner_id}", SUPERUSER_ID, SUPERUSER_ID))
cr.execute("SELECT setval('res_partner_id_seq', (SELECT MAX(id) FROM res_partner));")
_logger.info(f"[OWS Repair] {len(MISSING_PARTNERS)} fehlende Partner hinzugefügt.")
cr.commit()
# Automatischer Start in odoo-bin shell
if 'env' in globals():
insert_missing_partners(env.cr, env.registry)

View File

@ -1,177 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<record id="cat_einweisungen" model="product.category">
<field name="name">Einweisungen</field>
</record>
<record id="cat_maschinennutzung" model="product.category">
<field name="name">Maschinennutzung</field>
</record>
<record id="prod_3d_druck_30_minuten" model="product.product">
<field name="name">3D Druck (30 Minuten)</field>
<field name="default_code" />
<field name="list_price">0.25</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_bandschleifer_1_minute" model="product.product">
<field name="name">Bandschleifer (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_bandsäge_1_minute" model="product.product">
<field name="name">Bandsäge (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_cnc_fräse_1_minute" model="product.product">
<field name="name">CNC Fräse (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_cnc_sicherheitseinweisung" model="product.product">
<field name="name">CNC Sicherheitseinweisung</field>
<field name="default_code" />
<field name="list_price">25.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_drehbank_1_minute" model="product.product">
<field name="name">Drehbank (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_einweisung_3d_drucker_delta" model="product.product">
<field name="name">Einweisung 3D Drucker Delta</field>
<field name="default_code" />
<field name="list_price">15.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_3d_drucker_prusa" model="product.product">
<field name="name">Einweisung 3D Drucker Prusa</field>
<field name="default_code" />
<field name="list_price">20.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_bandsäge" model="product.product">
<field name="name">Einweisung Bandsäge</field>
<field name="default_code" />
<field name="list_price">15.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_drehbank" model="product.product">
<field name="name">Einweisung Drehbank</field>
<field name="default_code" />
<field name="list_price">20.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_fks" model="product.product">
<field name="name">Einweisung FKS</field>
<field name="default_code" />
<field name="list_price">20.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_hobel" model="product.product">
<field name="name">Einweisung Hobel</field>
<field name="default_code" />
<field name="list_price">15.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_laser" model="product.product">
<field name="name">Einweisung Laser</field>
<field name="default_code" />
<field name="list_price">15.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_metallfräse" model="product.product">
<field name="name">Einweisung Metallfräse</field>
<field name="default_code" />
<field name="list_price">20.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_schweißgerät" model="product.product">
<field name="name">Einweisung Schweißgerät</field>
<field name="default_code" />
<field name="list_price">10.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_einweisung_in_maschinelle_holzverbindungen" model="product.product">
<field name="name">Einweisung in maschinelle Holzverbindungen</field>
<field name="default_code" />
<field name="list_price">15.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_einweisungen" name="categ_id" />
</record>
<record id="prod_formatkreissäge_1_minute" model="product.product">
<field name="name">Formatkreissäge (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_fräse___deckel_1_minute" model="product.product">
<field name="name">Fräse - Deckel (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_hobel_1_minute" model="product.product">
<field name="name">Hobel (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_laser_aktivminute" model="product.product">
<field name="name">Laser (Aktivminute)</field>
<field name="default_code" />
<field name="list_price">0.7000000000000001</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_sandstrahlbox_1_minute" model="product.product">
<field name="name">Sandstrahlbox (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.2</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_schweißgerät_1_minute" model="product.product">
<field name="name">Schweißgerät (1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.2</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_schweißkabine_eigenes_schweißgerät___1_minute" model="product.product">
<field name="name">Schweißkabine (eigenes Schweißgerät - 1 Minute)</field>
<field name="default_code" />
<field name="list_price">0.1</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
<record id="prod_sonstige_dienstleistungen_nutzung" model="product.product">
<field name="name">Sonstige Dienstleistungen/Nutzung</field>
<field name="default_code" />
<field name="list_price">1.0</field>
<field name="available_in_pos">True</field>
<field ref="cat_maschinennutzung" name="categ_id" />
</record>
</odoo>

View File

@ -1,2 +0,0 @@
/opt/odoo/odoo/odoo-bin shell -d hobbyhimmel < /home/odoo/custom_addons/open_workshop/data/export_products_and_categories.py

View File

@ -1,20 +0,0 @@
# /opt/odoo/odoo/odoo-bin shell -d <alte datebase> < export_categories.py
import csv
from odoo import api, SUPERUSER_ID
import os
categories = env['product.category'].search([('name', 'in', ['Einweisungen', 'Maschinennutzung'])])
file_path = os.path.join(os.getcwd(), 'product_category.csv')
with open(file_path, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['id', 'name', 'parent_id/id'])
for cat in categories:
xml_id = f"open_workshop.cat_{cat.name.lower().replace(' ', '_')}"
parent_id = cat.parent_id and f"base.{cat.parent_id.xml_id}" or ''
writer.writerow([xml_id, cat.name, parent_id])
# Aufruf in odoo shell z.B.:
# env = odoo.api.Environment(cr, SUPERUSER_ID, {})
# export_categories(env)

View File

@ -1,26 +0,0 @@
# /opt/odoo/odoo/odoo-bin shell -d <alte datebase> < export_products.py
import csv
from odoo import api, SUPERUSER_ID
import os
# Kategorien suchen
category_names = ['Einweisungen', 'Maschinennutzung']
categories = env['product.category'].search([('name', 'in', category_names)])
products = env['product.product'].search([('categ_id', 'in', categories.ids)])
file_path = os.path.join(os.getcwd(), 'product_product.csv')
with open(file_path, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['id', 'name', 'default_code', 'list_price', 'categ_id/id', 'available_in_pos'])
for prod in products:
cat_xml_id = f"open_workshop.cat_{prod.categ_id.name.lower().replace(' ', '_')}"
xml_id = f"open_workshop.prod_{prod.default_code or prod.name.lower().replace(' ', '_')}"
writer.writerow([
xml_id,
prod.name,
prod.default_code or '',
prod.list_price,
cat_xml_id,
'1' if prod.available_in_pos else '0'
])

View File

@ -1,47 +0,0 @@
# -*- coding: utf-8 -*-
# /opt/odoo/odoo/odoo-bin shell -d <alte datebase> < export_products_and_categories.py
import xml.etree.ElementTree as ET
def xml_safe_id(name):
return name.lower().replace(' ', '_').replace('/', '_').replace('(', '').replace(')', '').replace('-', '_')
def export_categories_and_products(env):
root = ET.Element("odoo")
# Export Kategorien
categories = env['product.category'].search([
('name', 'in', ['Einweisungen', 'Maschinennutzung'])
])
for cat in categories:
record = ET.SubElement(root, "record", {
"id": f"cat_{xml_safe_id(cat.name)}",
"model": "product.category"
})
ET.SubElement(record, "field", name="name").text = cat.name
if cat.parent_id:
ET.SubElement(record, "field", name="parent_id", attrib={"ref": f"cat_{xml_safe_id(cat.parent_id.name)}"})
# Export Produkte
products = env['product.product'].search([
('categ_id.name', 'in', ['Einweisungen', 'Maschinennutzung'])
])
for product in products:
record = ET.SubElement(root, "record", {
"id": f"prod_{xml_safe_id(product.name)}",
"model": "product.product"
})
ET.SubElement(record, "field", name="name").text = product.name or ''
ET.SubElement(record, "field", name="default_code").text = product.default_code or ''
ET.SubElement(record, "field", name="list_price").text = str(product.list_price or 0.0)
ET.SubElement(record, "field", name="available_in_pos").text = "True"
if product.categ_id:
ET.SubElement(record, "field", name="categ_id", attrib={"ref": f"cat_{xml_safe_id(product.categ_id.name)}"})
tree = ET.ElementTree(root)
tree.write("data_product_and_categories.xml", encoding="utf-8", xml_declaration=True)
print("✅ XML export saved to data_product_and_categories.xml")
# Automatischer Start in odoo-bin shell
if 'env' in globals():
export_categories_and_products(env)

View File

@ -1 +0,0 @@
/opt/odoo/odoo/odoo-bin -d hobbyhimmel13_dev -i open_workshop --stop-after-init

View File

@ -1,50 +0,0 @@
<odoo>
<record id="machine_prusa_training_prod_einweisung_3d_drucker_prusa" model="ows.machine.training">
<field name="machine_id" ref="machine_prusa"/>
<field name="training_id" ref="prod_einweisung_3d_drucker_prusa"/>
</record>
<record id="machine_formatkreissaege_usage_prod_formatkreissäge_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_formatkreissaege"/>
<field name="product_id" ref="prod_formatkreissäge_1_minute"/>
</record>
<record id="machine_bandsaege_holz_usage_prod_bandsäge_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_bandsaege_holz"/>
<field name="product_id" ref="prod_bandsäge_1_minute"/>
</record>
<record id="machine_bandsaege_holz_training_prod_einweisung_bandsäge" model="ows.machine.training">
<field name="machine_id" ref="machine_bandsaege_holz"/>
<field name="training_id" ref="prod_einweisung_bandsäge"/>
</record>
<record id="machine_kreissaege_metall_usage_prod_formatkreissäge_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_kreissaege_metall"/>
<field name="product_id" ref="prod_formatkreissäge_1_minute"/>
</record>
<record id="machine_bandsaege_metall_usage_prod_bandsäge_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_bandsaege_metall"/>
<field name="product_id" ref="prod_bandsäge_1_minute"/>
</record>
<record id="machine_bandsaege_metall_training_prod_einweisung_bandsäge" model="ows.machine.training">
<field name="machine_id" ref="machine_bandsaege_metall"/>
<field name="training_id" ref="prod_einweisung_bandsäge"/>
</record>
<record id="machine_drehbank_usage_prod_drehbank_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_drehbank"/>
<field name="product_id" ref="prod_drehbank_1_minute"/>
</record>
<record id="machine_drehbank_training_prod_einweisung_drehbank" model="ows.machine.training">
<field name="machine_id" ref="machine_drehbank"/>
<field name="training_id" ref="prod_einweisung_drehbank"/>
</record>
<record id="machine_fraese_usage_prod_cnc_fräse_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_fraese"/>
<field name="product_id" ref="prod_cnc_fräse_1_minute"/>
</record>
<record id="machine_fraese_usage_prod_fräse___deckel_1_minute" model="ows.machine.product">
<field name="machine_id" ref="machine_fraese"/>
<field name="product_id" ref="prod_fräse___deckel_1_minute"/>
</record>
<record id="machine_fraese_training_prod_einweisung_metallfräse" model="ows.machine.training">
<field name="machine_id" ref="machine_fraese"/>
<field name="training_id" ref="prod_einweisung_metallfräse"/>
</record>
</odoo>

View File

@ -1 +0,0 @@
/opt/odoo/odoo/odoo-bin -d hobbyhimmel --update=open_workshop --dev=all --stop-after-init

2
log/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,11 @@
{
"folders": [
{
"path": "."
},
{
"path": "../../../usr/lib/python3/dist-packages/odoo"
}
],
"settings": {}
}

View File

@ -0,0 +1,3 @@
from . import models
from . import controllers

View File

@ -0,0 +1,39 @@
{
'name': 'POS Open Workshop',
'license': 'AGPL-3',
'version': '18.0.1.0.1',
'summary': 'Erstellt Maschinenfreigaben basierend auf POS-Einweisungsprodukten',
'depends': ['base', 'account', 'hr','product','sale','contacts','point_of_sale'],
'author': 'matthias.lotz',
'category': 'Point of Sale',
'data': [
'security/ir.model.access.csv',
'views/machine_product_training_views.xml',
'views/menu_views.xml',
'views/machine_area_views.xml',
'views/machine_views.xml',
'views/res_partner_view.xml',
'data/data.xml',
],
'installable': False, # Wird durch open_workshop_base ersetzt
'assets': {
'web.assets_backend': [
'open_workshop/static/src/css/category_color.css',
],
'point_of_sale._assets_pos': [
'open_workshop/static/src/css/pos.css',
'open_workshop/static/src/js/ows_machine_access_list.js',
'open_workshop/static/src/js/ows_pos_customer_sidebar.js',
'open_workshop/static/src/js/ows_pos_sidebar.js',
'open_workshop/static/src/js/ows_product_screen_template_patch.js',
'open_workshop/static/src/xml/ows_machine_access_list.xml',
'open_workshop/static/src/xml/ows_pos_customer_sidebar.xml',
'open_workshop/static/src/xml/ows_pos_sidebar.xml',
'open_workshop/static/src/xml/ows_product_screen_template_patch.xml',
],
},
'description': """
Diese App erstellt Maschinenfreigaben basierend auf POS-Einweisungsprodukten.
Die App ist für den Einsatz in der Odoo-Version 18.0 konzipiert.
""",
}

View File

@ -1,11 +1,14 @@
# Datei: controllers/pos_access.py
from odoo import http from odoo import http
from odoo.http import request from odoo.http import request
class OpenWorkshopPOSController(http.Controller): class OpenWorkshopPOSController(http.Controller):
@http.route('/open_workshop/partner_access', type='json', auth='user') @http.route('/open_workshop/partner_access', type='json', auth='user')
def get_partner_machine_access(self, partner_id): def get_partner_machine_access(self, **kwargs):
partner_id = kwargs.get('params', {}).get('partner_id')
if not partner_id:
return {"error": "Missing partner_id"}
Machine = request.env['ows.machine'].sudo() Machine = request.env['ows.machine'].sudo()
return Machine.get_access_list_grouped(partner_id) return Machine.get_access_list_grouped(partner_id)

View File

@ -15,22 +15,31 @@ class HREmployee(models.Model):
def anonymize_for_testsystem(self): def anonymize_for_testsystem(self):
"""Benennt Admin-Angestellten um und archiviert alle anderen für das Testsystem.""" """Benennt Admin-Angestellten um und archiviert alle anderen für das Testsystem."""
admin_user = self.env['res.users'].search([('name', '=', 'Administrator')], limit=1) admin_user = self.env['res.users'].search([('name', '=', 'Administrator')], limit=1)
if not admin_user:
_logger.error("[OWS] Administrator-Benutzer nicht gefunden!")
return
_logger.info(f"[OWS] Administrator-Benutzer gefunden: {admin_user.name} (ID: {admin_user.id})") _logger.info(f"[OWS] Administrator-Benutzer gefunden: {admin_user.name} (ID: {admin_user.id})")
admin_employee = self.search([('user_id', '=', admin_user.id)], limit=1)
# Suche auch archivierte Employees
admin_employee = self.with_context(active_test=False).search([('user_id', '=', admin_user.id)], limit=1)
if admin_employee: if admin_employee:
# Administrator-Employee reaktivieren und umbenennen
admin_employee.write({ admin_employee.write({
'name': 'TESTSYSTEM', 'name': 'TESTSYSTEM',
'job_title': 'Testumgebung', 'job_title': 'Testumgebung',
'work_email': False, 'work_email': 'office@hobbyhimmel.de',
'work_phone': False, 'work_phone': False,
'active': True, # Reaktivieren falls archiviert
}) })
_logger.info("[OWS] Admin-Angestellter wurde umbenannt.") _logger.info(f"[OWS] Admin-Angestellter reaktiviert und umbenannt: {admin_employee.name} (ID: {admin_employee.id})")
else: else:
_logger.warning("[OWS] Kein Angestellter für user_admin gefunden.") _logger.warning("[OWS] Kein Angestellter für Administrator gefunden.")
return
# Alle anderen Angestellten archivieren # Alle anderen Angestellten archivieren (auch bereits archivierte berücksichtigen)
other_employees = self.search([('id', '!=', admin_employee.id)]) other_employees = self.with_context(active_test=False).search([('id', '!=', admin_employee.id)])
other_employees.write({'active': False}) other_employees.write({'active': False})
_logger.info("[OWS] %d Angestellte archiviert.", len(other_employees)) _logger.info("[OWS] %d Angestellte archiviert.", len(other_employees))
@ -168,24 +177,21 @@ class ResPartner(models.Model):
def _compute_machine_access_html(self): def _compute_machine_access_html(self):
areas = self.env['ows.machine.area'].search([], order="name") areas = self.env['ows.machine.area'].search([], order="name")
for partner in self: for partner in self:
html = "<div class='tab-content'><div class='tab-pane active' id='machine_access_tab'>" html = ""
html += "<div class='o_group'>"
for area in areas: for area in areas:
html += "<table class='o_group o_inner_group o_group_col_6'><tbody>"
# Bereichsüberschrift
html += f""" html += f"""
<div class="o_form_sheet">
<h3 class="o_form_label">{area.name}</h3>
<table class="table table-sm table-bordered o_form_table">
<thead>
<tr> <tr>
<td colspan="3" style="width: 100%;"> <th>Maschine</th>
<div class="o_horizontal_separator">{area.name}</div> <th>Status</th>
</td> <th>Datum</th>
</tr> <th>Gültig bis</th>
<tr>
<td class="o_td_label"><label class="o_form_label"></label></td>
<td class="o_td_label"><label class="o_form_label">Datum</label></td>
<td class="o_td_label"><label class="o_form_label">Gültig bis</label></td>
</tr> </tr>
</thead>
<tbody>
""" """
machines = self.env['ows.machine'].search([('area_id', '=', area.id)], order="name") machines = self.env['ows.machine'].search([('area_id', '=', area.id)], order="name")
@ -195,25 +201,26 @@ class ResPartner(models.Model):
('partner_id', '=', partner.id), ('partner_id', '=', partner.id),
('machine_id', '=', machine.id), ('machine_id', '=', machine.id),
], limit=1) ], limit=1)
icon = "<span class='fa fa-check text-success'></span>" if access else "<span class='fa fa-times text-danger'></span>" icon = '<span class="text-success fa fa-check"/>' if access else '<span class="text-danger fa fa-times"/>'
date_granted = access.date_granted.strftime('%Y-%m-%d') if access and access.date_granted else "-" date_granted = access.date_granted.strftime('%Y-%m-%d') if access and access.date_granted else "-"
date_expiry = access.date_expiry.strftime('%Y-%m-%d') if access and access.date_expiry else "-" date_expiry = access.date_expiry.strftime('%Y-%m-%d') if access and access.date_expiry else "-"
html += f""" html += f"""
<tr> <tr>
<td class="o_td_label"><label class="o_form_label">{icon} {machine.name}</label></td> <td>{machine.name}</td>
<td class="o_td_field">{date_granted}</td> <td>{icon}</td>
<td class="o_td_field">{date_expiry}</td> <td>{date_granted}</td>
</tr> <td>{date_expiry}</td>
</tr>
""" """
html += "</tbody></table>" html += "</tbody></table></div>"
html += "</div></div></div>"
partner.machine_access_html = html partner.machine_access_html = html
@api.model @api.model
def migrate_existing_partners(self): def migrate_existing_partners(self):
""" """
@ -378,6 +385,7 @@ class OwsUser(models.Model):
('partner_unique', 'unique(partner_id)', 'Jeder Partner darf nur einen OWS-Datensatz haben.') ('partner_unique', 'unique(partner_id)', 'Jeder Partner darf nur einen OWS-Datensatz haben.')
] ]
AVAILABLE_COLORS = [ AVAILABLE_COLORS = [
('#000000', 'schwarz'), ('#000000', 'schwarz'),
('#ff0000', 'Rot'), ('#ff0000', 'Rot'),
@ -389,7 +397,7 @@ AVAILABLE_COLORS = [
('#ffff00', 'Gelb'), ('#ffff00', 'Gelb'),
('#FF9800', 'Orange'), ('#FF9800', 'Orange'),
('#795548', 'Braun'), ('#795548', 'Braun'),
('#1f1f1f', 'Grau'), ('#ffffff', 'Weiss'),
] ]
class OwsMachineArea(models.Model): class OwsMachineArea(models.Model):
@ -429,6 +437,8 @@ class OwsMachineArea(models.Model):
for rec in self: for rec in self:
rec.color_name = label_dict.get(rec.color_hex, 'Unbekannt') rec.color_name = label_dict.get(rec.color_hex, 'Unbekannt')
class OwsMachine(models.Model): class OwsMachine(models.Model):
_name = 'ows.machine' _name = 'ows.machine'
_table = 'ows_machine' _table = 'ows_machine'
@ -457,10 +467,10 @@ class OwsMachine(models.Model):
} }
rec.category_icon = icon_map.get(rec.category, '') rec.category_icon = icon_map.get(rec.category, '')
description = fields.Text(string="Gerätebeschreibung", translate=True, help="Beschreibung der Maschine oder des Geräts.") description = fields.Text()
active = fields.Boolean(string="Aktive", default=True, help="Ist die Maschine oder das Gerät aktiv? Inaktive Maschinen werden nicht mehr in der POS-Ansicht angezeigt.") active = fields.Boolean(default=True)
area_id = fields.Many2one('ows.machine.area', string='Bereich', help="Bereich in der Werkstatt, in dem die Maschine oder das Gerät steht.") area_id = fields.Many2one('ows.machine.area', string='Bereich', help="Bereich, in dem die Maschine oder das Gerät steht.")
product_ids = fields.One2many('ows.machine.product', 'machine_id', string="Nutzungsprodukte", help="Dies ist das zugehörige Produkt, falls die Maschine oder das Geräte eine zeitliche Nutzungsgebühr hat.") product_ids = fields.One2many('ows.machine.product', 'machine_id', string="Nutzungsprodukte")
product_names = fields.Char(string="Liste der Nutzungsprodukte", compute="_compute_product_using_names", store=False,) product_names = fields.Char(string="Liste der Nutzungsprodukte", compute="_compute_product_using_names", store=False,)
training_ids = fields.One2many('ows.machine.training', 'machine_id', string="Einweisungsprodukte") training_ids = fields.One2many('ows.machine.training', 'machine_id', string="Einweisungsprodukte")
training_names = fields.Char(string="Liste der Einweisungsprodukte", compute="_compute_product_training_names", store=False,) training_names = fields.Char(string="Liste der Einweisungsprodukte", compute="_compute_product_training_names", store=False,)
@ -510,10 +520,10 @@ class OwsMachine(models.Model):
- 'security_id': Sicherheits-ID des Nutzers (str oder ''). - 'security_id': Sicherheits-ID des Nutzers (str oder '').
- 'rfid_card': RFID-Kartennummer des Nutzers (str oder ''). - 'rfid_card': RFID-Kartennummer des Nutzers (str oder '').
- 'birthday': Geburtstag des Nutzers (str oder ''). - 'birthday': Geburtstag des Nutzers (str oder '').
""" """
partner = self.env['res.partner'].browse(partner_id) partner = self.env['res.partner'].browse(partner_id)
areas = self.env['ows.machine.area'].search([], order="name") areas = self.env['ows.machine.area'].search([], order="name")
_logger.info("Access RPC called with partner_id=%s", partner_id)
access_by_area = [] access_by_area = []
for area in areas: for area in areas:
machines = self.search([('area_id', '=', area.id), ('category', '=', 'red')], order="name") machines = self.search([('area_id', '=', area.id), ('category', '=', 'red')], order="name")
@ -544,6 +554,7 @@ class OwsMachine(models.Model):
} }
class OwsMachineAccess(models.Model): class OwsMachineAccess(models.Model):
_name = 'ows.machine.access' _name = 'ows.machine.access'
_table = 'ows_machine_access' _table = 'ows_machine_access'
@ -564,7 +575,7 @@ class OwsMachineAccess(models.Model):
class OwsMachineProduct(models.Model): class OwsMachineProduct(models.Model):
_name = 'ows.machine.product' _name = 'ows.machine.product'
_table = 'ows_machine_product' _table = 'ows_machine_product'
_description = 'OWS: Zurordnung Produkt der Nutzung zur die Maschine' _description = 'OWS: Zuordnung Produkt der Nutzung zu der Maschine'
product_id = fields.Many2one('product.product', required=True, domain=[('available_in_pos', '=', True)], ondelete='cascade') product_id = fields.Many2one('product.product', required=True, domain=[('available_in_pos', '=', True)], ondelete='cascade')
machine_id = fields.Many2one('ows.machine', required=True, ondelete='cascade') machine_id = fields.Many2one('ows.machine', required=True, ondelete='cascade')
@ -572,7 +583,7 @@ class OwsMachineProduct(models.Model):
class OwsMachineTraining(models.Model): class OwsMachineTraining(models.Model):
_name = 'ows.machine.training' _name = 'ows.machine.training'
_table = 'ows_machine_training' _table = 'ows_machine_training'
_description = 'OWS: Zurordnung Produkt der Einweisung zur die Maschine' _description = 'OWS: Zuordnung Produkt der Einweisung zu der Maschine'
training_id = fields.Many2one('product.product', required=True, domain=[('available_in_pos', '=', True)], ondelete='cascade') training_id = fields.Many2one('product.product', required=True, domain=[('available_in_pos', '=', True)], ondelete='cascade')
machine_id = fields.Many2one('ows.machine', required=True, ondelete='cascade') machine_id = fields.Many2one('ows.machine', required=True, ondelete='cascade')

View File

@ -5,18 +5,19 @@ from collections import defaultdict
import logging import logging
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
_logger.info("✅ pos_order.py geladen") _logger.info("✅ pos_order.py geladen Test 2")
# debugpy.listen(("0.0.0.0", 5678)) #debugpy.listen(("0.0.0.0", 5678))
# print("✅ debugpy wartet auf Verbindung (Port 5678) ...") print("✅ debugpy wartet auf Verbindung (Port 5678) ...")
# Optional: Starte erst, wenn VS Code verbunden ist # Optional: Starte erst, wenn VS Code verbunden ist
# debugpy.wait_for_client() #debugpy.wait_for_client()
class PosOrder(models.Model): class PosOrder(models.Model):
_inherit = 'pos.order' _inherit = 'pos.order'
def _process_order(self, order, draft, existing_order): def _process_order(self, order, existing_order):
pos_order_id = super(PosOrder, self)._process_order(order, draft, existing_order) _logger.info("🚨 DEBUG: _process_order wurde aufgerufen mit order: %s", order.get('name', 'unbekannt'))
pos_order_id = super(PosOrder, self)._process_order(order, existing_order)
pos_order = self.browse(pos_order_id) pos_order = self.browse(pos_order_id)
training_products = self.env['ows.machine.training'].search([]) training_products = self.env['ows.machine.training'].search([])

View File

@ -0,0 +1,9 @@
.category-color-circle {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 50%;
margin-left: 8px;
vertical-align: middle;
border: 1px solid #444;
}

View File

@ -0,0 +1,57 @@
.custompane {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.ows-sidebar {
flex: 1 1 auto;
width: 220px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.order-entry:hover { cursor: pointer; }
.order-entry.selected { background-color: #007bff; color: white; }
.ows-customer-list {
flex: 1 1 auto;
overflow-y: auto;
min-height: 0; /* notwendig für Scrollbar */
}
.client-details-grid {
flex-shrink: 0;
max-height: 60%;
overflow-y: auto;
background: #fff;
}
.pos *::-webkit-scrollbar {
width: 8px;
height:8px;
}
.sidebar-line {
display: flex;
justify-content: space-between;
gap: 0.5em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0.2em 0;
}
.sidebar-date {
flex-shrink: 0;
}
.sidebar-name {
flex-shrink: 1;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
}

View File

@ -0,0 +1,72 @@
// @odoo-module ows_machine_access_list.js
import { Component, useState } from "@odoo/owl";
import { useBus } from "@web/core/utils/hooks";
import { usePos } from "@point_of_sale/app/store/pos_hook";
import { rpc } from "@web/core/network/rpc";
import { registry } from "@web/core/registry";
export class OwsMachineAccessList extends Component {
static template = 'open_workshop.OwsMachineAccessList';
setup() {
this.pos = usePos();
this.state = useState({
client: null,
grouped_accesses: [],
security_briefing: false,
security_id: '',
rfid_card: '',
birthday: '',
});
// 🔁 Reagiere auf Partnerwechsel über den Odoo-Bus
useBus(this.env.bus, 'partner-changed', () => {
this.updateAccessList();
});
// 🔃 Beim Mounten initiale Daten laden
this.updateAccessList();
}
async updateAccessList() {
const order = this.pos.get_order();
const partner = order?.get_partner?.();
this.state.client = partner || null;
if (!partner) {
this.state.grouped_accesses = [];
this.state.security_briefing = false;
this.state.security_id = '';
this.state.rfid_card = '';
this.state.birthday = '';
return;
}
try {
const data = await rpc("/open_workshop/partner_access", {
params: { partner_id: partner.id },
});
this.state.grouped_accesses = data.access_by_area || [];
this.state.security_briefing = data.security_briefing;
this.state.security_id = data.security_id;
this.state.rfid_card = data.rfid_card;
this.state.birthday = data.birthday;
} catch (error) {
console.error("Fehler beim Laden der Einweisungen:", error);
this.state.grouped_accesses = [];
this.state.security_briefing = false;
this.state.security_id = '';
this.state.rfid_card = '';
this.state.birthday = '';
}
}
}
registry.category("templates").add("open_workshop.OwsMachineAccessList", OwsMachineAccessList);

View File

@ -0,0 +1,54 @@
// @odoo-module ows_pos_customer_sidebar.js
import { Component } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";
import { usePos } from "@point_of_sale/app/store/pos_hook";
import { _t } from "@web/core/l10n/translation";
import { ask } from "@web/core/confirmation_dialog/confirmation_dialog";
export class OwsPosCustomerSidebar extends Component {
static template = "open_workshop.OwsPosCustomerSidebar";
setup() {
this.pos = usePos(); // ✅ Holt dir Zugriff auf den zentralen POS-Store
this.dialog = useService("dialog");
}
addOrder() {
this.pos.add_new_order(); // ✅ Neue Order wird aktive Order
this.pos.showScreen("ProductScreen");
this.pos.selectPartner();
this.env.bus.trigger('partner-changed'); // ✅ Event manuell auslösen
}
async removeCurrentOrder() {
this.pos.onDeleteOrder(this.pos.get_order())
}
openTicketScreen() {
this.pos.showScreen("TicketScreen");
}
// 🔧 FIXED: Zugriff auf Order-Liste korrigiert
getFilteredOrderList() {
return this.pos.get_open_orders();
}
getDate(order) {
const date = new Date(order.date_order);
const dd = String(date.getDate()).padStart(2, '0');
const mm = String(date.getMonth() + 1).padStart(2, '0');
const hh = String(date.getHours()).padStart(2, '0');
const mi = String(date.getMinutes()).padStart(2, '0');
return `${dd}.${mm}. ${hh}:${mi}`;
}
getPartner(order) {
return order.get_partner()?.name || "Kein Kunde";
}
selectOrder(order) {
this.pos.set_order(order);
this.env.bus.trigger('partner-changed');
}
}

View File

@ -0,0 +1,11 @@
// ows_pos_sidebar.js
// @odoo-module
import { Component } from "@odoo/owl";
import { OwsPosCustomerSidebar } from "./ows_pos_customer_sidebar";
import { OwsMachineAccessList } from "./ows_machine_access_list";
export class OwsPosSidebar extends Component {
static template = "open_workshop.OwsPosSidebar";
static components = { OwsPosCustomerSidebar, OwsMachineAccessList };
}

View File

@ -0,0 +1,15 @@
// product_screen_template_patch.js
// @odoo-module
import { registry } from "@web/core/registry";
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
import { OwsPosSidebar } from "./ows_pos_sidebar";
class OwsProductScreen extends ProductScreen {
static components = Object.assign({}, ProductScreen.components, {
OwsPosSidebar,
});
}
registry.category("pos_screens").remove("ProductScreen");
registry.category("pos_screens").add("ProductScreen", OwsProductScreen);

View File

@ -0,0 +1,76 @@
<t t-name="open_workshop.OwsMachineAccessList">
<div class="client-details-grid p-2 small">
<!-- ✅ Sicherheitsbereich -->
<t t-if="state.client">
<div class="client-details-header">
<ul>
<li><span class="client-details-label">Einweisungen</span></li>
</ul>
<div class="client-details-area border" t-att-style="'border: solid 3px #ffffff; margin: 5px;'">
<ul>
<li class="client-detail">
<span class="detail client-details-vvow_briefing"></span>
<span class="briefinglabel">Werkstatt</span>
</li>
<li class="client-detail">
<t t-if="!state.security_briefing">
<span class="detail client-details-vvow_briefing_error"></span>
</t>
<t t-if="state.security_briefing">
<span class="detail client-details-vvow_briefing"></span>
</t>
<span class="briefinglabel">Haftungsausschluss</span>
</li>
<t t-if="!state.security_briefing">
<li class="client-detail">
<ul class="subpoints">
<span class="detail client-details-vvow_sec_briefing_error">Bitte Prüfen‼</span>
</ul>
</li>
</t>
<t t-if="state.security_briefing">
<ul class="subpoints">
<li class="client-detail">
<span class="label">Id:</span>
<span class="detail client-details-vvow_security_id">
<t t-esc="state.security_id || 'N/A'" />
</span>
</li>
<li class="client-detail">
<span class="label">Geburtstag:</span>
<span class="detail client-details-vvow_security_id">
<t t-esc="state.birthday || 'N/A'" />
</span>
</li>
</ul>
</t>
</ul>
</div>
</div>
</t>
<!-- ✅ Maschinenliste: immer sichtbar, gefiltert -->
<t t-foreach="state.grouped_accesses" t-as="area" t-key="area.area">
<t t-if="area.machines.length > 0">
<div class="client-details-area" t-att-style="'border: solid 3px ' + area.color_hex + '; margin: 5px;'">
<ul>
<t t-foreach="area.machines" t-as="machine" t-key="machine.name">
<li class="client-detail">
<span t-attf-class="detail {{ machine.has_access ? 'client-details-vvow_briefing' : 'client-details-vvow_briefing_error' }}">
<t t-esc="machine.has_access ? '✅' : '❌'" />
</span>
<span class="briefinglabel"><t t-esc="machine.name"/></span>
</li>
</t>
</ul>
</div>
</t>
</t>
</div>
</t>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="open_workshop.OwsPosCustomerSidebar" owl="1">
<div class="ows-sidebar p-2 bg-light border-end h-100">
<div class="ows-sidebar-header mb-2 d-flex justify-content-between align-items-center">
<button class="btn btn-secondary" t-on-click="openTicketScreen">Orders</button>
<div>
<button class="btn btn-sm btn-success me-1" t-on-click="addOrder">+</button>
<button class="btn btn-sm btn-danger" t-on-click="removeCurrentOrder"></button>
</div>
</div>
<div class="ows-customer-list overflow-auto">
<t t-foreach="getFilteredOrderList()" t-as="order" t-key="order.uid">
<!--div class="order-entry p-1 rounded mb-1 border"
t-att-class="order === pos.get_order() ? 'bg-primary text-white' : 'bg-white'"
t-on-click="() => selectOrder(order)"-->
<div t-att-class="'order-entry' + (order === pos.get_order() ? ' selected' : '')" t-on-click="() => this.selectOrder(order)">
<div class="sidebar-line">
<span class="sidebar-date"><t t-esc="getDate(order)"/></span>
<span class="sidebar-name" t-att-title="getPartner(order)"><t t-esc="getPartner(order)"/></span>
</div>
</div>
</t>
</div>
</div>
</t>
</templates>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="open_workshop.OwsPosSidebar" owl="1">
<div class="custompane d-flex flex-column border-end bg-200">
<OwsPosCustomerSidebar />
<OwsMachineAccessList />
</div>
</t>
</templates>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="point_of_sale.ProductScreen" t-inherit="point_of_sale.ProductScreen" t-inherit-mode="extension">
<xpath expr="//div[contains(@class, 'leftpane')]" position="before">
<OwsPosSidebar />
</xpath>
</t>
</templates>

View File

@ -0,0 +1,8 @@
<odoo>
<template id="assets_open_workshop" inherit_id="point_of_sale._assets_pos">
<xpath expr="." position="inside">
<script type="text/javascript" src="/open_workshop/static/src/js/machine_access_sidebar.js"/>
<link rel="stylesheet" type="text/css" href="/open_workshop/static/src/css/pos.css"/>
</xpath>
</template>
</odoo>

View File

@ -4,7 +4,7 @@
<record id="action_machine_area_list" model="ir.actions.act_window"> <record id="action_machine_area_list" model="ir.actions.act_window">
<field name="name">Maschinenbereiche</field> <field name="name">Maschinenbereiche</field>
<field name="res_model">ows.machine.area</field> <field name="res_model">ows.machine.area</field>
<field name="view_mode">tree,form</field> <field name="view_mode">list,form</field>
</record> </record>
<!-- Menüpunkt unter Maschinen > Konfiguration --> <!-- Menüpunkt unter Maschinen > Konfiguration -->
@ -15,10 +15,11 @@
<field name="name">ows.machine.area.tree</field> <field name="name">ows.machine.area.tree</field>
<field name="model">ows.machine.area</field> <field name="model">ows.machine.area</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree> <list>
<field name="name"/> <field name="name"/>
<field name="color_hex" widget="color_picker"/> <field name="color_hex_value" string="Farbe (Hex)"/>
</tree> <field name="color_name" string="Farbname"/>
</list>
</field> </field>
</record> </record>
@ -30,7 +31,8 @@
<form string="Maschinenbereich"> <form string="Maschinenbereich">
<group> <group>
<field name="name"/> <field name="name"/>
<field name="color_hex" widget="color_picker"/> <field name="color_hex"/>
<field name="color_name" readonly="1"/>
</group> </group>
</form> </form>
</field> </field>

View File

@ -4,10 +4,10 @@
<field name="name">ows.machine.product.tree</field> <field name="name">ows.machine.product.tree</field>
<field name="model">ows.machine.product</field> <field name="model">ows.machine.product</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree editable="bottom"> <list editable="bottom">
<field name="machine_id"/> <field name="machine_id"/>
<field name="product_id" domain="[('categ_id.name', '=', 'Maschinennutzung')]"/> <field name="product_id" domain="[('categ_id.name', '=', 'Maschinennutzung')]"/>
</tree> </list>
</field> </field>
</record> </record>
@ -16,10 +16,10 @@
<field name="name">ows.machine.training.tree</field> <field name="name">ows.machine.training.tree</field>
<field name="model">ows.machine.training</field> <field name="model">ows.machine.training</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree editable="bottom"> <list editable="bottom">
<field name="machine_id"/> <field name="machine_id"/>
<field name="training_id" domain="[('categ_id.name', '=', 'Einweisungen')]"/> <field name="training_id" domain="[('categ_id.name', 'in', ['Einweisungen', 'Kurse'])]"/>
</tree> </list>
</field> </field>
</record> </record>
@ -27,7 +27,7 @@
<record id="action_machine_product" model="ir.actions.act_window"> <record id="action_machine_product" model="ir.actions.act_window">
<field name="name">Maschinen-Nutzungsprodukte</field> <field name="name">Maschinen-Nutzungsprodukte</field>
<field name="res_model">ows.machine.product</field> <field name="res_model">ows.machine.product</field>
<field name="view_mode">tree</field> <field name="view_mode">list</field>
<field name="view_id" ref="view_machine_product_tree"/> <field name="view_id" ref="view_machine_product_tree"/>
<field name="help" type="html"> <field name="help" type="html">
<p>Verwalte die Zuordnung von Maschinen zu Nutzungsprodukten.</p> <p>Verwalte die Zuordnung von Maschinen zu Nutzungsprodukten.</p>
@ -38,7 +38,7 @@
<record id="action_machine_training" model="ir.actions.act_window"> <record id="action_machine_training" model="ir.actions.act_window">
<field name="name">Maschinen-Einweisungsprodukte</field> <field name="name">Maschinen-Einweisungsprodukte</field>
<field name="res_model">ows.machine.training</field> <field name="res_model">ows.machine.training</field>
<field name="view_mode">tree</field> <field name="view_mode">list</field>
<field name="view_id" ref="view_machine_training_tree"/> <field name="view_id" ref="view_machine_training_tree"/>
<field name="help" type="html"> <field name="help" type="html">
<p>Verwalte die Zuordnung von Maschinen zu Einweisungsprodukten.</p> <p>Verwalte die Zuordnung von Maschinen zu Einweisungsprodukten.</p>

View File

@ -5,19 +5,20 @@
<field name="name">ows.machine.tree</field> <field name="name">ows.machine.tree</field>
<field name="model">ows.machine</field> <field name="model">ows.machine</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree> <list>
<field name="category_icon" string="⚙" readonly="1"/> <field name="category_icon" string="⚙" readonly="1"/>
<field name="name"/> <field name="name"/>
<field name="category"/> <field name="category"/>
<field name="code"/> <field name="code"/>
<field name="area_id" widget="many2one_color"/> <field name="area_id" widget="many2one_color"/>
<field name="product_names"/> <field name="product_names"/>
<field name="training_names"/> <field name="training_names"/>
<field name="storage_location"/> <field name="storage_location"/>
<field name="purchase_price"/> <field name="purchase_price"/>
<field name="purchase_date"/> <field name="purchase_date"/>
<field name="active"/> <field name="active"/>
</tree>
</list>
</field> </field>
</record> </record>
@ -29,15 +30,13 @@
<form string="Maschine"> <form string="Maschine">
<sheet> <sheet>
<group> <group>
<field name="category_icon" string="⚙" readonly="1"/>
<field name="name"/> <field name="name"/>
<field name="category"/> <field name="category"/>
<field name="category_icon" string="⚙" readonly="1"/>
<field name="code"/> <field name="code"/>
<field name="area_id"/> <field name="area_id"/>
</group> </group>
<group> <group>
<field name="description"/> <field name="description"/>
<field name="storage_location"/> <field name="storage_location"/>
<field name="purchase_price"/> <field name="purchase_price"/>
@ -45,23 +44,23 @@
<field name="active"/> <field name="active"/>
</group> </group>
<!-- Neue --> <!-- Notebook für Produkte und Einweisungen -->
<notebook> <notebook>
<page string="Nutzungsprodukte"> <page string="Nutzungsprodukte">
<field name="product_ids" context="{'default_machine_id': active_id}"> <field name="product_ids" context="{'default_machine_id': id}">
<tree editable="bottom"> <list editable="bottom">
<field name="product_id" domain="[('categ_id.name', '=', 'Maschinennutzung')]" /> <field name="product_id" domain="[('categ_id.name', '=', 'Maschinennutzung')]" />
</tree> </list>
</field> </field>
</page> </page>
<page string="Einweisungsprodukte"> <page string="Einweisungsprodukte">
<field name="training_ids" context="{'default_machine_id': active_id}"> <field name="training_ids" context="{'default_machine_id': id}">
<tree editable="bottom"> <list editable="bottom">
<field name="training_id" domain="[('categ_id.name', 'in', ['Einweisungen', 'Kurse'])]" /> <field name="training_id" domain="[('categ_id.name', 'in', ['Einweisungen', 'Kurse'])]" />
</tree> </list>
</field> </field>
</page> </page>
</notebook> </notebook>
</sheet> </sheet>
</form> </form>
</field> </field>

View File

@ -4,14 +4,14 @@
<record id="action_machine_list" model="ir.actions.act_window"> <record id="action_machine_list" model="ir.actions.act_window">
<field name="name">Maschinen</field> <field name="name">Maschinen</field>
<field name="res_model">ows.machine</field> <field name="res_model">ows.machine</field>
<field name="view_mode">tree,form</field> <field name="view_mode">list,form</field>
</record> </record>
<!-- Trainingsprodukt-Liste --> <!-- Trainingsprodukt-Liste -->
<record id="action_training_product_list" model="ir.actions.act_window"> <record id="action_training_product_list" model="ir.actions.act_window">
<field name="name">Einweisungs-Produkte</field> <field name="name">Einweisungs-Produkte</field>
<field name="res_model">ows.machine.product</field> <field name="res_model">ows.machine.product</field>
<field name="view_mode">tree,form</field> <field name="view_mode">list,form</field>
</record> </record>
<!-- Menüstruktur --> <!-- Menüstruktur -->
@ -59,10 +59,10 @@
<field name="name">ows.machine.product.tree</field> <field name="name">ows.machine.product.tree</field>
<field name="model">ows.machine.product</field> <field name="model">ows.machine.product</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree> <list>
<field name="product_id"/> <field name="product_id"/>
<field name="machine_id"/> <field name="machine_id"/>
</tree> </list>
</field> </field>
</record> </record>

View File

@ -1,46 +1,62 @@
<odoo> <odoo>
<!-- Zentrale View für alle drei Tabs in garantierter Reihenfolge --> <!-- Entfernt die Partner-Warnung (Duplicate Bank Accounts) in res.partner
<record id="view_partner_form_inherit_open_workshop_tabs" model="ir.ui.view"> <record id="patch_res_partner_duplicate_warning" model="ir.ui.view">
<field name="name">res.partner.form.ows.tabs</field> <field name="name">res.partner.remove.duplicate.bank.warning</field>
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/> <field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="priority" eval="10"/> <field name="priority" eval="99"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//page[@name='sales_purchases']" position="before"> <xpath expr="//div[@name='warning_tax' and @class='alert alert-warning oe_edit_only']" position="replace"/>
</field>
</record>-->
<!-- Tab 1: HOBBYHIMMEL Basis --> <!-- Entfernt die Bankkonto-Warnung in res.partner.bank
<page name="ows_basic" string="HOBBYHIMMEL Basis"> <record id="patch_res_partner_bank_duplicate_warning" model="ir.ui.view">
<group name="container_row_2"> <field name="name">res.partner.bank.remove.duplicate.warning</field>
<group string="Sicherheit"> <field name="model">res.partner.bank</field>
<field name="security_briefing"/> <field name="inherit_id" ref="account.view_partner_bank_form_inherit_account"/>
<field name="security_id"/> <field name="priority" eval="99"/>
</group> <field name="arch" type="xml">
<group string="Zugang"> <xpath expr="//div[@class='alert alert-warning']" position="replace"/>
<field name="rfid_card"/> </field>
</group> </record> -->
</group>
</page>
<!-- Tab 2: HOBBYHIMMEL Einweisungen (HTML) --> <!-- Zentrale View für alle drei Tabs in garantierter Reihenfolge -->
<page name="ows_machine_access_html" string="HOBBYHIMMEL Einweisungen">
<field name="machine_access_html" readonly="1" widget="html"/>
</page>
<!-- Tab 3: Einweisungen (Liste) --> <record id="view_partner_form_inherit_open_workshop_tabs" model="ir.ui.view">
<page name="ows_machine_access_list" string="Einweisungen (Liste)"> <field name="name">res.partner.form.ows.tabs</field>
<field name="machine_access_ids"> <field name="model">res.partner</field>
<tree> <field name="inherit_id" ref="base.view_partner_form"/>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<xpath expr="//notebook" position="inside">
<page name="ows_machine_access" string="Offene Werkstatt (Hobbyhimmel)">
<!-- EINWEISUNG: Zwei Felder nebeneinander -->
<group name="container_row_2" string="Sicherheitseinweisung" col="2">
<field name="security_briefing"/>
<field name="security_id"/>
</group>
<!-- MASCHINENFREIGABEN: Volle Breite -->
<group string="Maschinenfreigaben" col="2">
<field name="machine_access_ids" colspan="2" context="{'default_partner_id': id}" nolabel="1">
<list>
<field name="machine_id"/> <field name="machine_id"/>
<field name="date_granted"/> <field name="date_granted"/>
<field name="date_expiry"/> <field name="date_expiry"/>
<field name="granted_by_pos"/> <field name="granted_by_pos"/>
</tree> </list>
</field> </field>
</page> </group>
</xpath> <!-- ÜBERSICHT: Volle Breite -->
</field> <group string="Maschinenfreigaben Übersicht" >
</record> <field name="machine_access_html" colspan="2" readonly="1" widget="html" nolabel="1"/>
</group>
</page>
</xpath>
</field>
</record>
<!-- Geburtstag direkt nach der USt-ID --> <!-- Geburtstag direkt nach der USt-ID -->
<record id="view_partner_form_inherit_ows_birthday" model="ir.ui.view"> <record id="view_partner_form_inherit_ows_birthday" model="ir.ui.view">
@ -100,7 +116,7 @@
<!-- Optional: Kontakte-Action, falls gebraucht --> <!-- Optional: Kontakte-Action, falls gebraucht -->
<record id="contacts.action_contacts" model="ir.actions.act_window"> <record id="contacts.action_contacts" model="ir.actions.act_window">
<field name="view_mode">tree,kanban,form,activity</field> <field name="view_mode">list,kanban,form,activity</field>
</record> </record>
<record id="contacts.action_contacts_view_kanban" model="ir.actions.act_window.view"> <record id="contacts.action_contacts_view_kanban" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/> <field name="sequence" eval="1"/>

View File

@ -0,0 +1,102 @@
# Migration von pysftp zu paramiko
## Datum: 11. Januar 2026
## Hintergrund
Das Modul `auto_backup` verwendete bisher die Library `pysftp`, die seit mehreren Jahren nicht mehr aktiv gewartet wird und nicht mit neueren Versionen von `paramiko >= 3.0` kompatibel ist.
## Änderungen
### 1. Hauptmodul (models/db_backup.py)
- **Import geändert**: `import pysftp``import paramiko` + `import stat`
- **Neue sftp_connection() Methode**:
- Verwendet jetzt `paramiko.SSHClient()` und `paramiko.SFTPClient()` direkt
- Implementiert als Context Manager mit try/finally für sauberes Cleanup
- Unterstützt mehrere Private Key Typen (RSA, Ed25519, ECDSA)
- Automatische Host Key Policy mit `AutoAddPolicy()`
- **Neue Hilfsmethoden**:
- `_wrap_sftp_client()`: Wrapper-Klasse für SFTP-Client mit zusätzlichen Methoden
- `_sftp_makedirs()`: Rekursive Verzeichniserstellung auf Remote-Server (wie `mkdir -p`)
- **Exception Handling angepasst**:
- `pysftp.CredentialException``paramiko.AuthenticationException`
- `pysftp.ConnectionException``OSError`
- `pysftp.SSHException``paramiko.SSHException`
### 2. Manifest (__manifest__.py)
- **external_dependencies aktualisiert**:
- Entfernt: `"pysftp"`, `"paramiko<4.0.0"`
- Behalten: `"paramiko"` (ohne Versionsbeschränkung), `"cryptography"`
### 3. Tests (tests/test_db_backup.py)
- **Import geändert**: `import pysftp``import paramiko`
- **Test-Exception angepasst**: `TestConnectionException` erbt jetzt von `paramiko.SSHException`
- **Mock-Tests aktualisiert**:
- Alle `pysftp.Connection` Mocks durch `paramiko.SSHClient` und `paramiko.SFTPClient` Mocks ersetzt
- Tests berücksichtigen jetzt die mehrstufige Verbindungslogik (SSH → SFTP)
## Vorteile der Migration
1. **Moderne Library**: paramiko 4.0.0+ ist aktuell und wird aktiv gewartet
2. **Bessere Kompatibilität**: Funktioniert mit aktuellen Python und OpenSSH Versionen
3. **Mehr Kontrolle**: Direkter Zugriff auf paramiko APIs ermöglicht besseres Error Handling
4. **Zukunftssicher**: Keine veralteten Dependencies mehr
5. **Sicherheit**: Neuere paramiko Versionen haben bessere Sicherheits-Features
## Funktionale Änderungen
**KEINE** - Das Modul funktioniert genau wie vorher:
- Lokale Backups funktionieren unverändert
- SFTP Backups funktionieren mit:
- Passwort-Authentifizierung
- Private Key Authentifizierung (RSA, Ed25519, ECDSA)
- Private Key mit Passwort
- Automatische Verzeichniserstellung
- Cleanup alter Backups
## Getestet mit
- Python 3.12
- paramiko 4.0.0
- Odoo 18.0
## Rückwärtskompatibilität
Die Änderungen sind **vollständig rückwärtskompatibel** auf Anwenderebene:
- Alle bestehenden Backup-Konfigurationen funktionieren weiter
- Keine Änderungen an UI oder Datenmodell
- API bleibt unverändert
## Technische Details
### Private Key Unterstützung
Die neue Implementation probiert automatisch verschiedene Key-Typen:
1. RSA (Standard, am häufigsten)
2. Ed25519 (modern, sehr sicher)
3. ECDSA (Fallback)
### SFTP Verzeichnis-Erstellung
Die Methode `_sftp_makedirs()` erstellt rekursiv alle Parent-Verzeichnisse:
- Prüft von unten nach oben, welche Verzeichnisse existieren
- Erstellt fehlende Verzeichnisse in richtiger Reihenfolge
- Ignoriert "already exists" Fehler (EEXIST)
### Connection Cleanup
Der Context Manager garantiert:
- SFTP Client wird immer geschlossen
- SSH Client wird immer geschlossen
- Selbst bei Exceptions wird aufgeräumt
## Migrationshinweise für Entwickler
Falls Sie das Modul erweitert haben:
1. `pysftp.Connection()` → Context Manager `with rec.sftp_connection() as sftp:`
2. `remote.makedirs()``rec._sftp_makedirs(sftp, path)`
3. Exception-Handling anpassen (siehe oben)
4. `sftp` ist jetzt ein Wrapper-Objekt, das auf den echten `paramiko.SFTPClient` delegiert
## Support
Bei Fragen oder Problemen bitte Issue auf GitHub erstellen oder Pull Request einreichen.

View File

@ -0,0 +1,168 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
====================
Database Auto-Backup
====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:6069fbb878a731cb4ac25058910ed6564c72cfecbb647732f21616058b9d6453
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
:target: https://github.com/OCA/server-tools/tree/18.0/auto_backup
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-auto_backup
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
A tool for all your back-ups, internal and external!
**Table of contents**
.. contents::
:local:
Installation
============
Before installing this module, you need to execute:
::
pip3 install pysftp==0.2.9
Configuration
=============
Go to *Settings -> Database Structure -> Automated Backup* to create
your configurations for each database that you needed to backups.
Usage
=====
Keep your Odoo data safe with this module. Take automated back-ups,
remove them automatically and even write them to an external server
through an encrypted tunnel. You can even specify how long local backups
and external backups should be kept, automatically!
Connect with an FTP Server
--------------------------
Keep your data safe, through an SSH tunnel!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Want to go even further and write your backups to an external server?
You can with this module! Specify the credentials to the server, specify
a path and everything will be backed up automatically. This is done
through an SSH (encrypted) tunnel, thanks to pysftp, so your data is
safe!
Test connection
---------------
Checks your credentials in one click
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Want to make sure if the connection details are correct and if Odoo can
automatically write them to the remote server? Simply click on the Test
SFTP Connection button and you will get message telling you if
everything is OK, or what is wrong!
E-mail on backup failure
------------------------
Stay informed of problems, automatically!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do you want to know if the database backup succeeded or failed?
Subscribe to the corresponding backup setting notification type.
Run backups when you want
-------------------------
From the backups configuration list, press *More > Execute backup(s)* to
manually execute the selected processes.
|Try me on Runbot|
.. |Try me on Runbot| image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:target: https://runbot.odoo-community.org/runbot/149/11.0
Known issues / Roadmap
======================
- On larger databases, it is possible that backups will die due to Odoo
server settings. In order to circumvent this without frivolously
changing settings, you need to run the backup from outside of the main
Odoo instance. How to do this is outlined in `this blog
post <https://blog.laslabs.com/2016/10/running-python-scripts-within-odoos-environment/>`__.
- Backups won't work if list_db=False is configured in the instance.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20auto_backup%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Yenthe Van Ginneken
* Agile Business Group
* Grupo ESOC Ingenieria de Servicios
* LasLabs
* AdaptiveCity
Contributors
------------
- Yenthe Van Ginneken <yenthe.vanginneken@vanroey.be>
- Alessio Gerace <alessio.gerace@agilebg.com>
- Jairo Llopis <yajo.sk8@gmail.com>
- Dave Lasley <dave@laslabs.com>
- Andrea Stirpe <a.stirpe@onestein.nl>
- Aitor Bouzas <aitor.bouzas@adaptivecity.com>
- Simone Vanin <simone.vanin@agilebg.com>
- Vu Nguyen Anh <vuna2004@gmail.com>
- Alex Comba <alex.comba@agilebg.com>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/18.0/auto_backup>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models

View File

@ -0,0 +1,27 @@
# Copyright 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright 2015 Agile Business Group <http://www.agilebg.com>
# Copyright 2016 Grupo ESOC Ingenieria de Servicios, S.L.U. - Jairo Llopis
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Open Workshop Database Auto-Backup",
"summary": "Backups database",
"version": "18.0.1.0.1",
"author": "Yenthe Van Ginneken, "
"Agile Business Group, "
"Grupo ESOC Ingenieria de Servicios, "
"LasLabs, "
"AdaptiveCity, "
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Tools",
"depends": ["mail"],
"data": [
"data/ir_cron.xml",
"data/mail_message_subtype.xml",
"security/ir.model.access.csv",
"view/db_backup_view.xml",
],
"installable": True,
"external_dependencies": {"python": ["paramiko", "cryptography"]},
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="ir_cron_backup_scheduler_0" model="ir.cron">
<field name="name">Backup Scheduler</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field
name="nextcall"
eval="(datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d 03:00:00')"
/>
<field name="model_id" ref="model_db_backup" />
<field name="state">code</field>
<field name="code">model.action_backup_all()</field>
</record>
</odoo>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="mail_message_subtype_success" model="mail.message.subtype">
<field name="name">Backup Successful</field>
<field name="description">Database backup succeeded.</field>
<field name="res_model">db.backup</field>
<field name="default" eval="False" />
</record>
<record id="mail_message_subtype_failure" model="mail.message.subtype">
<field name="name">Backup Failed</field>
<field name="description">Database backup failed.</field>
<field name="res_model">db.backup</field>
<field name="default" eval="True" />
</record>
</odoo>

View File

@ -0,0 +1,408 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-08 03:36+0000\n"
"PO-Revision-Date: 2016-12-08 03:36+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Amharic (https://www.transifex.com/oca/teams/23907/am/)\n"
"Language: am\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Creado por"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Creado en"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""

View File

@ -0,0 +1,412 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Arabic (https://www.transifex.com/oca/teams/23907/ar/)\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "أنشئ بواسطة"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "أنشئ في"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "اسم العرض"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "المعرف"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "آخر تحديث بواسطة"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "آخر تحديث في"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "الاسم"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "آخر تعديل في"

View File

@ -0,0 +1,411 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Bulgarian (https://www.transifex.com/oca/teams/23907/bg/)\n"
"Language: bg\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Създадено от"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Създадено на"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Име за показване"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Последно обновено от"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Последно обновено на"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Име"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Последно обновено на"

View File

@ -0,0 +1,412 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Bosnian (https://www.transifex.com/oca/teams/23907/bs/)\n"
"Language: bs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Kreirao"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Kreirano"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Prikaži naziv"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Zadnji ažurirao"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Zadnje ažurirano"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Ime"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Zadnje mijenjano"

View File

@ -0,0 +1,411 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-03 10:08+0000\n"
"PO-Revision-Date: 2018-03-03 10:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Creat per"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Creat el"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Nom a mostrar"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Darrera Actualització per"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Darrera Actualització el"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Nom"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Darrera modificació el"

View File

@ -0,0 +1,411 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Czech (https://www.transifex.com/oca/teams/23907/cs/)\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Vytvořil(a)"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Vytvořeno"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Zobrazovaný název"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Naposled upraveno"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Naposled upraveno"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Název"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Naposled upraveno"

View File

@ -0,0 +1,412 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# Lukáš Spurný <lukasspurny8@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-03 10:08+0000\n"
"PO-Revision-Date: 2018-03-03 10:08+0000\n"
"Last-Translator: Lukáš Spurný <lukasspurny8@gmail.com>, 2018\n"
"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/"
"teams/23907/cs_CZ/)\n"
"Language: cs_CZ\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Vytvořil"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Vytvořeno"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Zobrazit název"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Naposledy aktualizováno"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Poslední aktualizace dne"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr "Metoda"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Název"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Poslední změna dne"

View File

@ -0,0 +1,411 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Danish (https://www.transifex.com/oca/teams/23907/da/)\n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Oprettet af"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Oprettet den"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Vist navn"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "Id"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Sidst opdateret af"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Sidst opdateret den"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Navn"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Sidst ændret den"

View File

@ -0,0 +1,421 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-03 10:08+0000\n"
"PO-Revision-Date: 2018-03-03 10:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr "/home/odoo/.ssh/id_rsa"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr "Absoluter Pfad zum Speichern der Sicherungen"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr "Automatisiertes Backup"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
"Automatische Sicherungen der Datenbank können wie folgt geplant werden:"
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr "Backup fehlgeschlagen"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
#, fuzzy
msgid "Backup Format"
msgstr "Backup fehlgeschlagen"
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr "Backup erfolgreich"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
#, fuzzy
msgid "Choose the format for this backup."
msgstr "Absoluter Pfad zum Speichern der Sicherungen"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Erstellt von"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Erstellt am:"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Anzeigename"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr "Ordner"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
"Gehen Sie zu Einstellungen / Technisch / Automation / Geplante Vorgänge"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr "Hilfe"
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Zuletzt aktualisiert von"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Zuletzt aktualisiert am"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr "Methode"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Name"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr "SFTP-Passwort"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr "SFTP-Port"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr "SFTP-Server"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr "SFTP Einstellungen"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr "Suchen Sie die Aktion mit dem Namen \"Backup Scheduler\"."
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
"Setzen Sie die Aktion auf aktiv und geben Sie an wie oft die Sicherungen "
"erstellt werden soll."
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr "Verbindung testen"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr "Der Port auf dem FTP-Server, der SSH/SFTP Anfragen annimmt."
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
"Der Benutzername mit dem die SFTP-Verbindung mit hergestellt werden soll. "
"Dies ist der Benutzer auf dem externen Server."
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
"Verwenden Sie SFTP mit Vorsicht! Dies schreibt Dateien auf externen Servern "
"unter dem Pfad, den Sie angeben."
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr "Warnung:"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr "john"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr "sftp.example.com"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Zuletzt geändert am"

View File

@ -0,0 +1,409 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: Greek (Greece) (https://www.transifex.com/oca/teams/23907/"
"el_GR/)\n"
"Language: el_GR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Δημιουργήθηκε στις"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Δημιουργήθηκε από"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Τελευταία Ενημέρωση από"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Τελευταία Ενημέρωση στις"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Ονομασία"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""

View File

@ -0,0 +1,412 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * auto_backup
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-18 02:29+0000\n"
"PO-Revision-Date: 2017-02-18 02:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2016\n"
"Language-Team: English (United Kingdom) (https://www.transifex.com/oca/"
"teams/23907/en_GB/)\n"
"Language: en_GB\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "/home/odoo/.ssh/id_rsa"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
msgid "Absolute path for storing the backups"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction
msgid "Action Needed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: auto_backup
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
msgid "Automated Backups"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Automatic backups of the database can be scheduled as follows:"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_failure
msgid "Backup Failed"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_format
msgid "Backup Format"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.ir_cron_backup_scheduler_0_ir_actions_server
msgid "Backup Scheduler"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,name:auto_backup.mail_message_subtype_success
msgid "Backup Successful"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
msgid ""
"Backups older than this will be deleted automatically. Set 0 to disable "
"autodeletion."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Basic backup configuration"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_name_unique
msgid "Cannot duplicate a configuration."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__backup_format
msgid "Choose the format for this backup."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__method
msgid "Choose the storage method for this backup."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Failed!"
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid "Connection Test Succeeded!"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
msgid "Created by"
msgstr "Created by"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
msgid "Created on"
msgstr "Created on"
#. module: auto_backup
#: model:ir.model,name:auto_backup.model_db_backup
msgid "Database Backup"
msgstr ""
#. module: auto_backup
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_failure
msgid "Database backup failed."
msgstr ""
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
#: model:mail.message.subtype,description:auto_backup.mail_message_subtype_success
msgid "Database backup succeeded."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
msgid "Days To Keep"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
msgid "Display Name"
msgstr "Display Name"
#. module: auto_backup
#. odoo-python
#: code:addons/auto_backup/models/db_backup.py:0
msgid ""
"Do not save backups on your filestore, or you will backup your backups too!"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Execute backup"
msgstr ""
#. module: auto_backup
#: model:ir.actions.server,name:auto_backup.action_server_backup
msgid "Execute backup(s)"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
msgid "Folder"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_follower_ids
msgid "Followers"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__has_message
msgid "Has Message"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Help"
msgstr ""
#. module: auto_backup
#: model:ir.model.constraint,message:auto_backup.constraint_db_backup_days_to_keep_positive
msgid "I cannot remove backups from the future. Ask Doc for that."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
msgid "ID"
msgstr "ID"
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
msgid "Last Updated by"
msgstr "Last Updated by"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
msgid "Last Updated on"
msgstr "Last Updated on"
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__local
msgid "Local disk"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_ids
msgid "Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__method
msgid "Method"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
msgid "Name"
msgstr "Name"
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_private_key
msgid ""
"Path to the private key file. Only the Odoo user should have read "
"permissions for that file."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_private_key
msgid "Private key location"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__method__sftp
msgid "Remote SFTP server"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
msgid "SFTP Password"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
msgid "SFTP Port"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
msgid "SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "SFTP Settings"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Search the action named 'Backup scheduler'."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Set the scheduler to active and fill in how often you want backups generated."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__smart_search
msgid "Smart Search"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
msgid "Summary of this backup process"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Test SFTP Connection"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
msgid ""
"The host name or IP address from your remote server. For example 192.168.0.1"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
msgid ""
"The password for the SFTP connection. If you specify a private key file, "
"then this is the password to decrypt it."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
msgid "The port on the FTP server that accepts SSH/SFTP calls."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
msgid ""
"The username where the SFTP connection should be made with. This is the user "
"on the external server."
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid ""
"Use SFTP with caution! This writes files to external servers under the path "
"you specify."
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
msgid "Username in the SFTP Server"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "Warning:"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields,help:auto_backup.field_db_backup__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "john"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__dump
msgid "pg_dump custom format (without filestore)"
msgstr ""
#. module: auto_backup
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_conf_form
msgid "sftp.example.com"
msgstr ""
#. module: auto_backup
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_format__zip
msgid "zip (includes filestore)"
msgstr ""
#~ msgid "Last Modified on"
#~ msgstr "Last Modified on"

Some files were not shown because too many files have changed in this diff Show More