Einsteiger: erfüllt Dolibarr meine Anforderungen?

Hallo!

Ich suche für mein kleinstmögliches Unternehmen nach 20 Jahren mit einer Eigenlösung (LibreOffice + OO-Basic) eine vernünftige ERP-Lösung, die preisgünstig, zukunftsfähig und nicht zu komplex ist und bin u.a. auf Dolibarr gestoßen.

Kurze Beschreibung meines Unternehmens:

  • Einzelunternehmen mit EÜR im Raum Koblenz/Eifel
  • Online-Versand über Webshop
  • CNC-Bearbeitung und Elektronikentwicklung (sowohl Eigenprodukte als auch Dienstleistung)
  • zu mir: Informatiker, gute Kenntnisse in Joomla/php-Programmierung

Meine Anforderungen wären:

  • Rechnungsstellung über Schnittstelle zum Shop (sowohl B2C, B2B, auch innergem. Lieferungen und nicht-EU-Ausland)
  • Angebotsherstellung
  • Anbindung von DHL/Etikettenerstellung per Zebra-Etikettendrucker
  • Kundenverwaltung
  • automatische Mahnungserinnerung
  • Lagerverwaltung der Verkaufsprodukte (passiert bisher im Shop selbst, eventuell mit Abgleich)
  • einfache Lagerverwaltung selbst genutzter Bauteile/Werkzeuge, einfach um sie auffindbar zu halten (“Wo finde ich das gesuchte: Welches Regal, welche Kiste?” reicht da eigentlich schon, Bestandsüberwachung erfolgt per “Augenmaß”, ich möchte nicht jede Schraube austragen :wink:
  • spätestens Ende des Jahres dann natürlich Umstellung auf E-Rechnung

Wie oben geschrieben: PHP und SQL sind für mich keine Fremdwörter, eine Offline-Lösung für Zugpferd-Rechnungen existiert bereits, Website wurde jetzt von mir inkl. Forumsmigration und Shopänderungen neu aufgesetzt. Alles hier und in der Produktion läuft unter Linux und OSS, sowohl Server, PCs, CNC-Maschinen, Entwicklung.

Das ist der grobe Rahmen. Die Einarbeitung und Migration soll über das Jahr nach und nach erfolgen, meine Selbstbaulösung läuft ja noch ganz gut.

Kann Dolibarr das soweit leisten? Ich denke, das meiste funktioniert. Wichtig wären die Punkte, wo ich eventuell selbst Hand anlegen muss.

Wenn noch weitere Infos nötig sind, so liefere ich die gerne nach.

Vielen Dank schon mal,
Christoph

Servus Christof,

Ich nutze Dolibarr seit 2022, bin auch ITler hatte aber nicht viel mit PHP zu tun.

Für mich als kleines IT Unternehmen war es die Richtige Entscheidung, auch wenn die Buchhaltung zu wünschen übrig ließ, hat es alles getan was ich brauche, ich habe dann noch etwas für Module wie Datev Export und X-E Rechnung investiert.

Ich Bilanziere, meine vorherige Software war von Sage, ein gutes Programm, aber nicht mehr Zeitgemäß.

So wie ich deine Fragen gelesen habe, sollte alles passen :ok_hand:

Lg

Jason

Hallo Jason,

Danke für Deine Einschätzung! Das hört sich doch schon recht gut an.
Ich habe mich gestern schon etwas umgesehen und der modulare Aufbau gefällt mir gut. Die Übernahme meiner Kundendatei sollte Dank der Importfunktion einfach zu bewerkstelligen sein.

Eine Frage zu den Lagern/Artikeln habe ich aber bereits. Vielleicht weiß da jemand eine Antwort:
Wo trage ich denn den Lagerplatz eines Artikels ein? Unter “NeuerArtikel” finde ich nur den Eintrag “Standardlager” - aber man sollte das doch schon genauer angeben können (Regal X, Ebene Y, Platz Z o.ä.).

Einen schönen Sonntag,
Christoph

Hallo,

Standard Lager ist genau Richtig, du kannst dort Regal 1 2 oder 3 hinterlegen genauso wie Keller 1 2 oder 3 etc.

Lg

Jason

Hallo Christoph,

wenn du zuerst die "Laberplätze” anlegst, kannst du bei jedem Produkt das Standardlager auswählen.

Vg,
Kim

Hallo Kim,

vielen Dank für den Hinweis. Also sollte ich im Prinzip für jede Kiste ein eigenes Lager anlegen. Gibt es dafür eine Automatik? Ich habe bspw. alleine in der Produktion 20 Regale (Buchstaben A bis T) mit je fünf Böden und pro Boden fünf Kisten. Es wäre schön, das nicht alles per Hand anlegen zu müssen. Zur Not bliebe ja noch Import über CSV, die ich leicht per Skript erzeugen könnte.

Für die Artikel selbst: ich kann ja eine Baumstruktur von Kategorien, zu denen die Artikel gehören, erstellen (Muttern → DIN234 → M6 → 1.4301 usw.).

Wenn ich mir dann bspw. alle Artikel einer bestimmten Kategorie anzeigen lassen möchte, gehe ich über Modul Produkte/Leistungen → Produkte → Liste und führe dort meine Suche aus?

Kann ich auch Suchen wie “Zeige mir alle Muttern M5 UND M6” durchführen?

Viele Grüße,
Christoph

könnte man so machen:

LAGER1 (Hauptlager)
├── LAGER1-A (Regal A)
│ ├── LAGER1-A-B1 (Boden 1)
│ │ ├── LAGER1-A-B1-1 (Box 1)
│ │ ├── LAGER1-A-B1-2 (Box 2)
│ │ ├── … bis Box 5
│ ├── LAGER1-A-B2 (Boden 2)
│ │ └── … 5 Boxen
│ └── … bis Boden 5
├── LAGER1-B (Regal B)
│ └── … gleiche Struktur
└── … bis Regal T

<?php /\*\* \* Script zum hierarchischen Anlegen von Warenlagern in Dolibarr \* \* Struktur: \* - Lager 1 \* - Regale A bis T (20 Regale) \* - Pro Regal 5 Böden (1-5) \* - Pro Boden 5 Boxen (1-5) \* \* Total: 1 + 20 + 100 + 500 = 621 Warenlager \* \* METHODE 1: Dolibarr API (empfohlen, sauber) \*/ // Dolibarr Umgebung laden - Automatische Pfad-Erkennung $res = 0; $possible_paths = \[ "/usr/share/dolibarr/htdocs/master.inc.php", // Debian/Ubuntu Standard "/var/www/html/dolibarr/htdocs/master.inc.php", // Apache Standard "/var/www/dolibarr/htdocs/master.inc.php", // Alternative dirname(\__FILE_\_) . "/../../htdocs/master.inc.php", // Relativ zum Script "/opt/dolibarr/htdocs/master.inc.php", // Custom Installation getcwd() . "/htdocs/master.inc.php", // Current Directory \]; foreach ($possible_paths as $path) { if (!$res && file_exists($path)) { echo "✓ Dolibarr gefunden: $path\\n"; $res = @include $path; if ($res) break; } } if (!$res) { echo "❌ FEHLER: Dolibarr master.inc.php nicht gefunden!\\n\\n"; echo "Gesuchte Pfade:\\n"; foreach ($possible_paths as $path) { echo " - $path\\n"; } echo "\\nBitte Script im Dolibarr-Verzeichnis ausführen oder Pfad anpassen.\\n"; die(); } require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; // Konfiguration $config = \[ 'main_ref' => 'LAGER1', 'main_label' => 'Hauptlager 1', 'main_location' => 'Standort Hauptlager', 'regale' => range('A', 'T'), // A bis T = 20 Regale 'boeden_per_regal' => 5, // 5 Böden pro Regal 'boxen_per_boden' => 5, // 5 Boxen pro Boden 'dry_run' => true // true = nur anzeigen, false = tatsächlich anlegen \]; echo "===========================================\\n"; echo "Warenlager Hierarchie Generator\\n"; echo "===========================================\\n\\n"; // Statistik $stats = \[ 'main' => 1, 'regale' => count($config\['regale'\]), 'boeden' => count($config\['regale'\]) \* $config\['boeden_per_regal'\], 'boxen' => count($config\['regale'\]) \* $config\['boeden_per_regal'\] \* $config\['boxen_per_boden'\] \]; $stats\['total'\] = $stats\['main'\] + $stats\['regale'\] + $stats\['boeden'\] + $stats\['boxen'\]; echo "Anzulegen:\\n"; echo "- 1 Hauptlager\\n"; echo "- {$stats\['regale'\]} Regale\\n"; echo "- {$stats\['boeden'\]} Böden\\n"; echo "- {$stats\['boxen'\]} Boxen\\n"; echo "- TOTAL: {$stats\['total'\]} Warenlager\\n\\n"; if ($config\['dry_run'\]) { echo "⚠️ DRY RUN MODE - Keine echten Änderungen!\\n"; echo " Setze 'dry_run' => false zum tatsächlichen Anlegen.\\n\\n"; } // =========================================== // METHODE 1: Dolibarr API (empfohlen) // =========================================== function createWarehouseAPI($ref, $description, $location, $parent_id = 0, $dry_run = true) { global $db, $conf, $user; if ($dry_run) { echo " \[DRY\] Würde anlegen: $ref - $description\\n"; return rand(1000, 9999); // Fake ID für Dry-Run } $warehouse = new Entrepot($db); $warehouse->ref = $ref; $warehouse->description = $description; $warehouse->lieu = $location; $warehouse->statut = 1; // Aktiv $warehouse->country_id = 1; // Deutschland $warehouse->fk_parent = $parent_id; $result = $warehouse->create($user); if ($result > 0) { echo " ✅ Angelegt: $ref (ID: $result)\\n"; return $result; } else { echo " ❌ FEHLER bei $ref: " . $warehouse->error . "\\n"; return false; } } echo "===========================================\\n"; echo "METHODE 1: Dolibarr API\\n"; echo "===========================================\\n\\n"; $created = 0; // 1. Hauptlager echo "1. Hauptlager anlegen...\\n"; $main_id = createWarehouseAPI( $config\['main_ref'\], $config\['main_label'\], $config\['main_location'\], 0, $config\['dry_run'\] ); if ($main_id) $created++; // 2. Regale echo "\\n2. Regale anlegen...\\n"; $regal_ids = \[\]; foreach ($config\['regale'\] as $regal) { $ref = $config\['main_ref'\] . '-' . $regal; $desc = 'Regal ' . $regal; $loc = 'Regal ' . $regal; $regal_id = createWarehouseAPI($ref, $desc, $loc, $main_id, $config\['dry_run'\]); if ($regal_id) { $regal_ids\[$regal\] = $regal_id; $created++; } } // 3. Böden echo "\\n3. Böden anlegen...\\n"; $boden_ids = \[\]; foreach ($config\['regale'\] as $regal) { if (!isset($regal_ids\[$regal\])) continue; for ($boden = 1; $boden <= $config\['boeden_per_regal'\]; $boden++) { $ref = $config\['main_ref'\] . '-' . $regal . '-B' . $boden; $desc = "Regal $regal - Boden $boden"; $loc = "Boden $boden"; $boden_id = createWarehouseAPI($ref, $desc, $loc, $regal_ids\[$regal\], $config\['dry_run'\]); if ($boden_id) { $boden_ids\[$regal\]\[$boden\] = $boden_id; $created++; } } } // 4. Boxen echo "\\n4. Boxen anlegen...\\n"; $box_count = 0; foreach ($config\['regale'\] as $regal) { if (!isset($boden_ids\[$regal\])) continue; for ($boden = 1; $boden <= $config\['boeden_per_regal'\]; $boden++) { if (!isset($boden_ids\[$regal\]\[$boden\])) continue; for ($box = 1; $box <= $config\['boxen_per_boden'\]; $box++) { $ref = $config\['main_ref'\] . '-' . $regal . '-B' . $boden . '-' . $box; $desc = "Regal $regal - Boden $boden - Box $box"; $loc = "Box $box"; $box_id = createWarehouseAPI($ref, $desc, $loc, $boden_ids\[$regal\]\[$boden\], $config\['dry_run'\]); if ($box_id) { $box_count++; $created++; } } } } echo "\\n===========================================\\n"; echo "FERTIG!\\n"; echo "===========================================\\n"; echo "Angelegt: $created von {$stats\['total'\]} Warenlagern\\n\\n"; ?>

Diese Datei ist nur ein dry run - ändert also noch nichts. Aber so könnte man es über die API machen.

Du kannst dich gerne direkt melden dann zeig ich dir paar Sachen schnell online.
Gerade was das Suchen/Filtern angeht ist vieles schneller online gezeigt.

Hallo Kim!

Vielen Dank für das Skript. Ich schaue mir das jetzt mal in Ruhe an und wenn ich soweit alles eingerichtet und mein Lager umgezogen habe, dann melde ich mich bzgl. online “Suchschulung” :slight_smile:

Und nebenbei werde ich mich mal etwas in die Entwickler-Doku einarbeiten.

Viele Grüße,

Christoph

Noch eine Ergänzung zum Skript:

Ein Fehler ist vorhanden - zumindest weigert er sich hier bei mir unter 22.0.4, mit dem Parameter $warehouse→ref zu arbeiten und wirft: ErrorFieldRequired

Ein Blick in die Klassendefinition von Entrepot zeigte dann auch, dass die Spalte in der Datenbank zwar ref heisst, in der Klasse aber label.

Man muss also in der Funktion createWarehouseAPI
$warehouse->ref = $ref;
ersetzen durch
$warehouse->label = $ref;

Das nur, falls jemand hier später das Skript findet und es nutzen möchte.
Ansonsten klappte es sehr gut - alle Positionen wurden erstellt :slight_smile:

Viele Grüße,
Christoph