Product Lifecycle Management (PLM) using webERP

This post is #2 in a series on using webERP, and is a work-in-progress. Search for “webERP” to find other posts in the series.

Product lifecycle management (PLM) is the act of consciously managing a product from concept through design, into manufacturing and sales, supporting on-going production and sales through sustaining engineering, and finally winding down. PLM integrates people, data, processes and business systems, and provides a trustable and transparent product information backbone for operations.

Features of using WebERP for PLM include:

  • Integrated data. Projects, people, hours, other expenses, purchase orders, production builds, bills of materials, etc., are conveniently managed in one controlled system.
  • A visible, trusted, change management process providing chain of truth.
  • Scales with number of users, items and complexity of item trees.

I will explore webERP’s PLM features using the Swift Construction Company’s development of the Aircraft Wireless as an example, following the SCC Product Management process

Goals

The goals of this exercise will be to:

  • Create child and parent items to model an assembly.
  • Define appropriate work centers.
  • Capture expected manufacturing labour.
  • Identify item vendor information for purchasing.
  • Identify item manufacturer information for purchasing through distribution.(manufacturer part number vs vendor part number).
  • Identify an appropriate change management or ECO process. COMING SOON 

Definitions

Here are some terms in the context I will be using them.

  • Revision Level. Each item has a unique revision level, indicating changes made to the item or its supporting documentation since it was initially defined. The revision level is changed following a well-defined sequence. 
  • Release. A release is the creation or update of a logical set of items and supporting documentation. This may be to publish information for review, to support processes such as purchasing or manufacturing, or to recognize a milestone in the development project.
  • ECO (Engineering Change Order). A well-defined process for making changes to a part or assembly, usually custom. 

Setup

Create Inventory Categories

The Swift Construction Company, like many engineering services and product companies, grew organizationally from a single-person engineering department to eventual separate mechanicals and electronics development teams. Knowing if a thing is a “mechanical thing”, or an “electronics, firmware, or basically anything but a mechanical thing” indicates which department is responsible for it.

As a result of the SCC’s organization structure, physical things are categorized as either either ELEC or MECH for raw materials and parts, or RADIOS for finished goods (currently the SCC’s only product line).  

Main > Setup > Inventory Setup > Inventory Categories Maintenance

ELEC Inventory Category

MECH Inventory Category

RADIOS Inventory Category

Create Units of Measure

An item’s Unit of Measure (UOM) specifies how the item is to be inventoried and consumed. webERP supports different purchase units, for example to purchase in US gallon jugs but inventory and consume in millilitres. 

A new unit of measure is typically created if needed when a new item is created, but using the SCC Aircraft Wireless development project documentation we can create all necessary units of measure now.

Main > Setup > Inventory Setup > Inventory Units of Measure

Create Vendors

A new vendor is typically created ad hoc, but using the SCC Aircraft Wireless development project documentation we can create each vendor now (vendors can also be imported from a CSV file). 

Main > Vendors > Add a New Vendor

Create Items

Create new items according to the SCC Aircraft Wireless development project. I will shjow details for creating sub-assembly 20000001-00 (a custom inductor), and the rest of the items and bills of materials will be similar.

20000001,"IND,830UH,AIRCRAFT WIRELESS"
|-- 90000001,"WIRE,MAGNET,38AWG,POLY"
|-- 90000002,"MAG,FERRITE ROD,1/4IN X 4IN,MATL=61"
\-- 90000003,"TAPE,ELECTRICAL,3/4"",BLUE,VINYL"

90000001-00 Magnet Wire

The unit of measure for the wire will be centimetres, meaning the wire will be inventoried and consumed by the centimeter. However, it will be purchased by the spool, which is the vendor unit of measure (the datasheet for the wire indicates a spool has 19,300 feet).

The consumption unit of measure will generally be the most relevant for any transaction other than purchasing or inventory control. When purchasing, the unit of measure will generally be determined by the vendor, and webERP supports a separate purchase unit when creating a purchase order. This means in an inventory audit that it will be necessary to convert from the counted number of full spools, add fractions of a spool for any partial spools, and convert to centimeters. However, the conversion factor can be found in the item master purchasing data, and the math is not too laborious.  

Items > Create New Item

Enter Purchasing Information

Items > Item Maintenance > Maintain Purchasing Data

Enter Standard Cost

The standard cost for cm UOM is C$0.00026308 per cm (C$154.83/spool x [ 1 / [ 19300ft x 30.48cm/ft ] ] ).

Items > Item Maintenance > Maintain Standard Cost

Upload Documentation

Upload the manufacturers’ datasheet to the Knowledge Base.

Items > Item Inquiries > Wiki Product Knowledge Base

I’m using the same template for each page. It is essentially a list of categories of typical documentation. It’s a judgement call at the time the part is created what is required though.

90000002-00 Ferrite Rod

Items > Create New Item

Enter Purchasing Information

Items > Item Maintenance > Maintain Purchasing Data

Enter Standard Cost

Items > Item Maintenance > Maintain Standard Cost

Upload Documentation

Upload the catalogue page, datasheet and application note to the Knowledge Base.

Items > Item Inquiries > Wiki Product Knowledge Base

90000003-00 Tape

Items > Create New Item

Enter Purchasing Information

Items > Item Maintenance > Maintain Purchasing Data

Enter Standard Cost

Items > Item Maintenance > Maintain Standard Cost

Upload Documentation

Upload the product datasheet and MSDS to the Knowledge Base.

Items > Item Inquiries > Wiki Product Knowledge Base

20000001-00 Inductor

Item 20000001-00 is a custom inductor that will be manufactured in-house using the parts listed in a Bill of Materials (BOM). An item must be explicitly specified as Manufactured in the Item Properties for a creation of an associated BOM to be allowed.

Items > Create New Item

Enter Standard Cost

Set the standard cost to be the total calculated cost including labor and any fixed overhead costs.

Items > Item Maintenance > Maintain Standard Cost

Enter Standard Price

Items which may be sold require pricing. It is expected field technicians may wish to purchase 20000001-00 for maintenance repair.

Items > Item Maintenance > Maintain Pricing

Create Bill of Materials

The raw material required to manufacture one item 20000001-00 are specified by creating a Bill-of-Materials, including quantities. The raw materials are also referred to as child items of the parent 20000001-00, and are set to auto-issue, which will simplify creating a manufacturing work order later.

Main > Manufacturing > Maintenance > Bills Of Material

 

 

Installing webERP

This post is the first in a series on using webERP. Search for “webERP” to find other posts in the series.

webERP is a mature open-source ERP system providing best practise, multi-user business administration and accounting tools over the web. webERP can be used with a wiki CMS to provide an integrated Knowledge Base. I will be installing MediaWiki, which is one of the supported wiki applications.

Goals

The goals of this exercise will be to:

  • Install webERP software.
  • Install MediaWiki software.
  • Configure webERP and MediaWiki for use.

Install Applications

I will be hosting webERP and MediaWiki on FreeBSD, a unix-like operating system (GNU/Linux is another popular unix-type operating system). The server has been previously configured with Apache 2.4 for the http (web) server and MariaDB 10.0 (compatible with MySQL) for the database server.

webERP

Copy the webERP software files to the server and configure the Apache web server.

  • Extract distribution to /usr/local/www/
  • Rename extracted directory webERP/ to weberp-4.13.1
  • Create soft link “weberp” to weberp-x.y.z
  • Create Apache virtual server e.g. http://weberp.dalescott.net

Access http://weberp.dalescott.net with a web browser to run the installer.

  • Language: US
  • Db user and password: root (only for install, future access will be changed to a dedicated user after installation)
  • Company name: e.g. Swift Construction Company
  • Install demo data: YES
  • User “admin” email: e.g. dale@dalescott.net
  • admin user password: (keep this safe)

After the installer has completed, change the database access user to a new database user with privileges to webERP databases only.

  • Create a new database user “weberp” with all privileges to the weberp and weberpdemo databases.
  • Edit the webERP configuration file weberp/config.php and change the database access user and password to the new dedicated user.

MediaWiki

Copy the MediaWiki software files to the server and configure the Apache web server.

  • Download a release archive.
  • Extract the distribution to /usr/local/www/ (which will create mediawiki-x.y.z/) 
  • Create a soft link “wiki” to mediawiki-x.y.z/
  • Create an Apache virtual server http://wiki.dalescott.net

Access http://wiki.dalescott.net/mw-config/index.php with a web browser to run the installer.

  • Name of wiki: webERP
  • User rights profile: Authorized editors only (public viewing is allowed)
  • Enable file uploads

Configure Applications

webERP

Log into webERP using the admin user credentials entered into the auto-installer and create new named user e.g. dalescott. The new user will be used for all subsequent work to identify the administration user specifically for audit purposes. 

  • email: e.g. dale@dalescott
  • system administrator privileges

The original admin user (created by the auto-installer) cannot be deleted due to a now existing audit trail.

Location

I will create a new location “Shopton” for the SCC headquarters.

Main > Setup > Inventory Setup > Inventory Locations Maintenance

Note: Delivery Address 1 must be given a value, otherwise a “missing delivery address” error will occur when later attempting to create a purchase order.

After creating the new location, change the location of the administration user to the new location (and of any other users). 

Currencies

I will create a new CAD currency as some items will need to be purchased in Canadian dollars. webERP will obtain currency exchange rates from either Google or the European Central Bank (Main > Setup > General > System Preferences).

Main > Setup > General Setup > Currencies Maintenance

“USD” is shown as the “Functional Currency” because United States is set as the SCC company currency in the Company Preferences.

Company Preferences

Operating practices for a specific company are configured in the Company Preferences screen (webERP supports multiple companies and the desired company is selected at login). 

Main > Setup > General > Company Preferences.

System Preferences

General system-wide behavior is configured in the System Preferences screen. I will quickly review some interesting parameters, and get into a bit more detail with a few specific parameters.

  • Date format: Y-m-d. I prefer ISO 8601 dates for clarity over familiarity (e.g. 2017-03-08 for March 8, 2017), which avoids the ambiguity of d/m/Y and m/d/Y.
  • Frequently Ordered Items: 0. I left this disabled but may experiment with it once the system has some orders entered.
  • Sales Order Allows Same Item Multiple Times: Yes. I will revisit this later, but at least initially I don’t want anything to block operation.
  • Languages to Maintain Translations for Item Descriptions: None. Don’t complicate things at least initially.
  • Picking note must be produced before an order can be delivered: No. I don’t want to complicate the process too soon.
  • Auto Update Exchange Rates Daily: Automatic. Source Exchange Rates From: Google. 
  • Create Debtor Codes Automatically: No. I want to use my own mnemonic codes, but set to Yes if you don’t care and would prefer to let the system assign a sequential integer.
  • Create Supplier Codes Automatically: No. I prefer to use my own mnemonic codes.
  • Country of operation: United States (used when calculating shipping costs).
  • Purchase Order Allows Same Item Multiple Times: Yes. I will revisit this later, but at least initially I don’t want anything to block operation.
  • Automatically authorise purchase orders if user has authority: Yes. I will disable this later so I can follow the approval process.
  • Financial year ends on: December (if only to avoid having to answer of why not calendar years).
  • Maximum Size in KB of uploaded images: 300. I left this at its default value, although some images and screenshots will likely require re-sizing before uploading.
  • Directory to store images: part_pics (directory already exists)
  • Directory to store reports: reports (directory already exists)
  • Wiki application: MediaWiki (I’m already familiar with MediaWiki), Wiki Path: http://wiki.dalescott.net/ 
  • Inventory Costing Method: Standard. webERP also supports weighted average, but Standard Costing behavior will be more obvious to start with.
  • Auto issue components: Yes. Automatically decrement items from stock according to the BOM for an Item when it is manufactured to reduce admin effort.
  • Prohibit Negative Stock: No. I’m pretty sure I will set this to Yes later, but prefer no blocking operations at least initially.
  • Log Severity Level: All, Path to log files: log. I want to see all possible log entries initially and can be reduced later (I also had to create the “log” directory and set ownership of the directory to the www:www, which is the Apache http server user on FreeBSD).
  • Controlled Items Defined At Work Order Entry: Yes. When set to yes, controlled items are defined at the time of the work order creation. Otherwise controlled items (serial numbers and batch/roll/lot references) are entered at the time the finished items are received against the work order
  • Auto Create Work Orders: Yes. Setting this parameter to Yes will ensure that when a sales order is placed if there is insufficient stock then a new work order is created at the default factory location
  • Default Factory Location: Shopton. This will be the default location for automatically created work orders.
  • Factory manager email: dale@dalescott.net, Purchasing manager email: dale@dalescott.net, Inventory manager email: dale@dalescott.net. I’m setting all email addresses to me for convenience so I see the traffic.
  • Using Smtp Mail: No. My server will route email from webERP out through my ISP’s mail server.

Main > Setup > System Preferences

Wiki Application

In particular, note the setting for “Wiki application”. When enabled by selecting a particular Wiki dialogue (MediaWiki, WackoWiki or DokuWiki), a link to the “Wiki Product Knowledge Base” will be shown in the Inquiries column of the main Items, Vendors and Customers screens (once an Item/Vendor/Customer has been selected).

You also need to set the root path to the wiki (that webERP will append to) in the system parameters screen. In my case, I needed a trailing “/” in the Wiki Path, but YMMV.

Database Maintenance

webERP can be configured to lock out users by setting Perform Database Maintenance at Logon to Allow SysAdmin Access Only. Only users with security profile “System Administrator” will be allowed to login or enter data when this is set, which is important when performing maintenance on the application code or database. A maintenance notice also appears on the login prompt when Allow SysAdmin Access Only is set.

Main > Setup > General > System Parameters

This parameter can also be used to periodically run the query “OPTIMIZE DATABASES” at set intervals. It is not clear how often this should be run, or even if there is a significant benefit. However, users will notice a slight delay during login when the it runs, it might have been a half-second with an almost empty Swift Construction Company database (on a older dual-core desktop PC with 4GB memory). If periodically running OPTIMIZE DATABASES is desired, you may consider creating an entry in the cron table to run the mysql command line interface, giving the query as a command argument.

MediaWiki

The webERP Knowledge Base, MediaWiki in my case, is a completely separate system from webERP, including separate users, user permissions, etc. webERP simply provides structured links into the Knowledge Base (with some variation depending on the wiki protocol selected in webERP Main > Setup > General > System Parameters > Wiki application).

I intentionally configured MediaWiki during install for public access, but required that a user be logged-in to create a new page, edit an existing page or upload a file. This allows anyone to see information, and in most cases get on with their job, without having to be concerned with logging into the Knowledge Base. For me, this is a nice balance of visibility and trust within a homogeneous organization. Users can also set their browsers to remember their login credentials and once set won’t be inconvenienced again (I wouldn’t necessarily recommend this when there are shared workstations, but then again many people use shared workstations and don’t control who the user is, it all depends….).

Upload File Types

I configured the permitted upload file types to include OpenOffice/LibreOffice files, dwg files and zip archives (see MediaWiki documentation).

$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg',
 'odt', 'ods', 'odp', 'odg',
 'txt', 'pdf', 'zip', 'dwg'
);

Site Logo

I also uploaded the SCC logo as a media file and edited LocalSettings.php to use new logo.

Summary

This completes basic webERP and MediaWiki installation and configuration.

ATK rocks on!

I received a blast-from-the-past email yesterday wanting to know how to format  ATK code for submitting a patch. I was going to simply refer them to the ATK GitHub project I helped create, but then thought I’d better check and see what’s been happening in the project lately (regular readers will be know I’ve been developing with Yii for the past couple year).

I was pleasantly surprised to find the project has been forked, and there’s been a lot of new development supported by the Italian company Sintattica. ATK was originally developed in Belgium, which proves open-source knows no national boundaries!

The new project still has some community relations work to do as the links and developer information in README.md haven’t been updated since forking, and there doesn’t seem to be a public issue tracker, but it seems ATK could be off to a great new beginning. There’s even a new development branch featuring PSR-4 compatibility and a modern class system!

It’s great to see ATK continue as a presence in the rapid web app development space, and it’s rewarding to think my efforts migrating the source from iBuilding’s Subversion repo to GitHub may have helped in some small way. With the buzz that new fad frameworks attract from their fanboyz before fading away, it’s refreshing to see a truly innovative idea continue. Thanks iBuildings and Ivo for starting the project, and thanks Sintattica for your support.

 

Build a FreeBSD-10 server with Apache, MariaDB, and php using binary packages

It has been traditional for a FreeBSD sysadmin to compile applications from source in the ports tree, but binary packages can now be used for basic needs which saves significant time.

This server is being built for Maestro development. It will be running on my Windows 10 laptop using VirtualBox, although it could just as easily run on bare metal.

Features will include:

  • FreeBSD 10.1-RELEASE Unix-like operating system.
  • Apache 2.4, MariaDB 5.5 and PHP 5.6 AMP stack (using mod_php).
  • Samba 3.6 and rsync (Samba to access Windows file shares as well as share the Maestro file vault to Windows clients, and rsync to synchronize the Maestro file vault to a Windows share).
  • A variety of handy utilities, including git and mdbtools (to import from a Parts&Vendors Jet4 mdb database file).

This post does not include a mail server or gateway, and also will be updated shortly to include infrastructure requirements for Maestro testing (using PHPUnit with Selenium). Maestro is being updated first to use Composer following current best practices, with Composer being used to install PHPUnit. 

Create Virtual Server

Create a new vm and specify BSD OS (FreeBSD) with 256 MB memory and a 20G system drive. Configure the network interface for NAT mode, and forward the IP ports being used from the vm (client) to Windows (host).

HTTPS (secure HTTP) will not be configured at this time. However, it will become the norm in the future.

ssh               host port 2222        client port 22
http              host port 8880        client port 80
mysql-tcp         host port 3336        client port 3306
mysql-udp         host port 3336        client port 3306

Download FreeBSD-10.2-RELEASE-i386.dvd1.iso from FreeBSD.org, boot the vm from the ISO, and perform a standard install (use 64-bit if you prefer, I still tend to create 32-bit virtual machines because I know it works and don’t need the extra address space). I will simply use root to admin the server, and will not create additional users during the install.

After installing the OS and rebooting into the new system, update the system to the latest release if you used an older install ISO, and also update the packages system (pkg, or pkgng in older references).

# freebsd-update upgrade -r 10.2-RELEASE
# freebsd-update install

# pkg update

Edit /etc/rc.conf to specify the hostname and DHCP network config.

hostname="whizzer.swiftconstructioncompany.net"
ifconfig_em0="DHCP"

sshd_enable="YES"
 
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

Edit /etc/hosts so that necessary hostnames resolve (10.0.2.15 is the default IP address for a VirtualBox vm, substitute if necessary).

I am requiring that the vm never be exposed to the internet by using hostname swiftconstructioncompany.net. A different hostname must be used if the vm will be exposed to the internet.

::1         localhost localhost.local
127.0.0.1   localhost localhost.local
127.0.0.1   localhost localhost.swiftconstructioncompany.net
10.0.2.15   whizzer.swiftconstructioncompany.net whizzer
10.0.2.15   whizzer.swiftconstructioncompany.net.

Edit /etc/ssh/sshd_config to permit remote root login only, and only using an ssh key (a password can still be used at the console if necessary).

AllowUsers root
PermitRootLogin YES
 
PasswordAuthentication no
ChallengeResponseAuthentication no
 
UsePAM yes

Copy root‘s public ssh key to /root/.ssh/authorized_keys and restart sshd.

# service sshd restart

Install Apache and php

The venerated Apache with mod_php will be used, and installing mod_php will first install Apache 2.x as a dependency.

# pkg install mod_php5

Edit /usr/local/etc/apache24/httpd.conf to specify the server name and when to use php.

# ServerAdmin: Your address, where problems with the server should be
ServerAdmin admin@whizzer.swiftconstructioncompany.net

# ServerName gives the name and port that the server uses to identify itself.
ServerName www.swiftconstructioncompany.net:80

# as per message from pkg install mod_php56
<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>

Edit /etc/rc.conf to start Apache at boot:

apache24_enable="YES"

Use the provided production PHP configuration file (or use the production file to suppress warnings and errors).

# cp /usr/local/etc/php.ini-development /usr/local/etc/php.ini

Edit php.ini to specify the server timezone.

# add default date timezone
date.timezone = "America/Edmonton"

# uncomment session.save_path
session.save_path = "/tmp"

Confirm that the PHP comnmand line tools were installed correctly (no errors means things are good).

# php -r "phpinfo ( );"

Test the Apache configuration and start Apache.

# service apache24 configtest
# service apache24 start

Test that Apache will serve HTML by browsing http://localhost:8880 to see the default Apache install page.

Test that Apache will execute PHP by displaying the output from phpinfo() in a web page. I like to explicitly configure Apache for each site or page served to avoid the possibility of accidentally creating a security risk. First create /usr/local/www/phpinfo/index.php, the PHP code for the “phpinfo website”.

<?php
 phpinfo();
?>

Next, create an Apache configuration file /usr/local/etc/apache24/Includes/phpinfo.conf.

Alias /phpinfo "/usr/local/www/phpinfo"

<Directory "/usr/local/www/phpinfo">
 Require all granted
</Directory>

Finally restart Apache,

# service apache24 restart

and browse to http://localhost:8880/phpinfo to confirm all is ok.

This post will be updated shortly to include the infrastructure for Maestro testing using PHPUnit and Selenium.

Install MariaDB

Install the MariaDB database server (and the mysql command line client). I haven’t tested Maestro with MariaDB v10.x yet, so will use MariaDB v5.5, which retains full compatibility with MySQL 5.5.

# pkg install mariadb55-server

Use the my-medium.cnf config file:

# cp /usr/local/share/mysql/my-medium.cnf /var/db/mysql/my.cnf

and edit it to default to InnoDB tables:

# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = /var/db/mysql
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /var/db/mysql
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

Install MariaDB’s management database and setup grant tables:

# cd /usr/local/
# mysql_install_db --user=mysql --basedir=/usr/local --basedir=/usr/local --datadir=/var/db/mysql

The –datadir option should not be necessary but must be specified if mysql_install_db cannot determine datadir (aka ldir) correctly.

Edit /etc/rc.conf to start MariaDB at boot.

mysql_enable="YES"

Start MariaDB.

# service mysql-server start

Configure the MariaDB root password:

> mysqladmin -u root password 'appleton'
> mysqladmin -u root -p -h localhost password 'appleton'
> mysqladmin -u root -p -h whizzer.swiftconstructioncompany.net password 'appleton'

If desired, grant root permission to connect remotely (e.g. to connect to MariaDB on the vm directly from the Windows host, or some other “remote” server).

> mysql -u root -p
mysql> grant all privileges on *.* to 'root'@'%' identified by 'appleton' with grant option;
mysql> exit;

Restart MariaDB to read the edited my.cnf file:

# service mysql-server restart

Run mysql_secure_installation as a double-check that all is ok.

# mysql_secure_installation

Install Samba and rsync

The venerable Samba v3 will be used for simple CIFS file sharing.

# pkg install samba3

Create the Maestro share directory.

# mkdir -p /usr/home/maestro
# chmod ugo+w /usr/home/maestro

Edit /usr/local/etc/smb.conf to configure Samba.

#======================= Global Settings =====================
[global]
workgroup = WORKGROUP
server string = Maestro Share
security = share
passdb backend = tdbsam
#======================= Share Definitions =====================
[maestro]
comment = Maestro Share
path = /usr/home/maestro
public = yes
read only = no

Edit /etc/rc.conf to start Samba at boot:

# samba3
samba_enable="YES"
winbindd_enable="YES"

Start Samba:

# service samba start

Install rsync.

# pkg install rsync

Install Utilities

Git

Git is used to clone the Maestro project repository.

Install Git.

# pkg install git

Configure git with your username and email. I prefer plain text without color-coding.

# git config --global user.name "Dale Scott"
# git config --global user.email "dale@dalescott.net"

# git config --global color.ui false
# git config --global color.diff false
# git config --global color.status false
# git config --global color.branch false
# git config --global color.interactive false

mdbtools

mdbtools is used by Maestro export data from Parts&Vendors, which uses a Microsoft Jet v4 database (colloquially called an Access database).

# pkg install mdbtools

flip

flip is useful for converting the occasional pesky Windows-format text file.

# pkg install flip