Local Food Cooperative Software


The Jist: This software operates on an order cycle instead of an “always open” system. Producers/farmers can log in and add products to their product catalog at anytime for sale. During a designated time, cooperative members place orders.
HomeWho’s Using It?DownloadsHow to HelpOther Resources

Upgrading from a prior 1.4.x version to 1.5.0

IMPORTANT: This procedure has not been thoroughly tested. It is compiled based upon known changes and experience with various partial upgrades. It is strongly recommend this process be undertaken on a test server with mirrored data rather than on a live production system and it is likely there will be points of difference in just about every system attempting to upgrade. Absolutely no guarantee is given. Please share your experience to help improve this document.

Updating the code – Method #1 – Using a patch file (the easy way – if it works)

NOTE: You will need to have shell-access for this procedure.

  1. Plan your work

    For major changes such as upgrades, it is a good idea to schedule a block of time when member usage will be at a minimum and when there will be no need to run critical functions for a while. That way, if something goes terribly wrong, you will have time to return your system to a stable configuration.

    Read through the entire upgrade process before beginning and be certain you know how to get back to your original setup – either by restoring a backup or by undoing the upgrade process itself. If you are not certain, find someone more experienced to help.

  2. Backup your web files

    The procedure you are about to perform will automatically modify many of your files and if it "goes bad" it can leave you with a mess. Be sure you have a working backup of your website and database contents. Many web hosting companies provide this service.

  3. Download the patch

    Download the v1.4.x to v1.5.0 patch and save it to your web server.

  4. Prepare to apply the patch

    Open a shell account to your web server and change to the directory immediately above DOCUMENT_ROOT. IMPORTANT: The patch assumes default configuration with a DOCUMENT_ROOT called public_html and all local food coop files in public_html/shop/. If that is not true for your setup, you must move the files – or copies of the files – into that configuration prior to running the patch.

  5. Apply the patch

    Execute the following command to apply the patch to your system:

    patch -Np1 < patchfile

    where patchfile is the path/name to the patch file you saved in step 1.

  6. What to expect

    Running the patch command will output a list of files as they are patched. Ideally, most of them will be silently patched with a message like

    patching file public_html/shop/producers/template.php

    but occasionally – particularly with the .htaccess files – it will complain, which is normal. If you are asked for some kind of confirmation about whether/how to patch individual files, it is probably a sign that the patch is going poorly and should be aborted. There are too many possibilities to discuss in detail here.

    The patch file was created from a v1.4.4 → v1.5.0 upgrade but it should work reasonably well with earlier versions also.

  7. Do a few things that patch did not finish

    Create a web-server writable shop/admin/temp/ directory. This directory is used for temporary storage of producer invoices when they are generated singly.

  8. Make necessary changes to the database

    Proceed to the database modification section below and perform the necessary steps.

Updating the code – Method #2 – Manual update (the tedious method)

NOTE: You will need a method for diffing files to accomplish this procedure. To make things easier, a graphical diff tool can speed the process of comparing files. One such tool that is available for Linux, Macintosh, and Windows platforms is DiffMerge but this author has never used it.

Alternative: The procedure below involves diffing files directly on the web server. It may be easier to follow a similar procedure with files saved on a local computer and upload the results to the web server.

  1. Download the full new source

    Download the full v1.5.0 source and extract it to a directory on your web server that is near – but different from – the active/live one. It might be useful to call the directory holding this version something like new.

  2. Download a new copy of the old source for comparison

    Download a clean copy of the source for the version you are currently using and extract it to another directory on your web server – also near but different from the active/live one. Review the installation instructions for that version and move all the files to the relative positions they would normally occupy. It might be useful to call the directory holding this version something like base.

  3. Compare and make changes

    Go through each file in your active/live installation and compare it with the files in the base structure. This will allow you to find all the changes that were made in your setup. These changes should be reflected in the corresponding files of the new structure.

  4. Switch to the new codebase

    Once you feel that all the relevant changes have been migrated to the new structure, exchange that directory with the active/live directory.

  5. Integrate files that were not considered

    Invoice files in the /shop/members/invoices/ directory will probably need to be moved over from the old active/live directory structure to the new one.

    Producer files in the /shop/producers/ directory will probably need to be moved over from the old active/live directory structure to the new one.

  6. Make necessary changes to the database

    Proceed to the next section and perform the necessary database modifications.

Database Modifications

The database schema is slightly different for each version of the local-food-coop software so there are some manual processes that need to be undertaken to make the data structure consistent with v1.5.x.

  1. Backup the database

    As usual, it is essential to backup the database – just in case something goes terribly wrong.

  2. Create a new table: producer_totals

    Execute the following query in your database to create a producer_totals table.

    CREATE TABLE
      producer_totals
      (
        pid int(10) unsigned NOT NULL auto_increment,
        producer_id varchar(5) default NULL,
        prod_total varchar(7) default NULL,
        delivery_id int(11) NOT NULL default '0',
        total_earned varchar(10) NOT NULL default '',
        amount_paid varchar(10) default NULL,
        last_modified timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
        sent_to_prdcr tinyint(1) default NULL,
        sent_back tinyint(1) default NULL,
        finalized tinyint(1) default NULL,
        invoice_content text NOT NULL,
        PRIMARY KEY  (pid)
      )
      
  3. Modify the members table to accommodate auth_type=sysadmin

    Execute the following query in your database. This will A) change members.auth_type from type "enum" to type "set" and B) add "sysadmin" and "institution" as possible auth_types. NOTE: you should first check to be sure all the possible auth_types in your members table are represented in the query).

    ALTER TABLE
      members
    CHANGE
      auth_type auth_type
    SET
      (
        'member',
        'producer',
        'administrator',
        'rtemanager',
        'cashier',
        'sysadmin',
        'institution'
      ) NOT NULL DEFAULT 'member' 
      
    member: All members should be of this type (not yet fully implemented).
    producer: All producers should be of this type (not yet fully implemented).
    administrator: Really this is "Producer Admin" and grants access to the producer administrative functions in the member’s area.
    rtemanager: Not yet implemented.
    cashier: Not yet implemented.
    sysadmin: Grants administrative access to the /shop/admin area of the site.
    institution: Grants the ability to shop for items that are marked as wholesale.
  4. Connect the administrative authorization auth_users_c table to the members table

    Rather than maintaining a separate auth_users_c table independent of the members table, which requires synchronization of passwords and other tedium, we will create a "view" into the members table and call it auth_users_c.

    First, take note of what members you have set up in the auth_users_c table to have administrative access to the /shop/admin/ section of the site. Then go to the members table and grant those members auth_type="sysadmin".

    Next, drop the auth_users_c table:

    DROP TABLE
      auth_users_c
      

    And finally, create a view of the members table that will only show auth_type="sysadmin" members:

    CREATE VIEW
      auth_users_c
      AS
        SELECT
          first_name,
          last_name,
          username_m ,
          password
        FROM
          members
        WHERE
          auth_type LIKE '%sysadmin%'
      
  5. Update the transactions_types table for membership fees accounting

    Modify and execute the following query to set up some useful membership adjustment types.

    IMPORTANT: Before running the query below be sure the ttype_id value (the first number in each VALUES section) does not collide with any existing values in the transactions_types table. The first three values (#15, #24, and #25) are likely to be modifications to your existing data. In that event, you may wish to update any values in the transactions table to these new values.

    INSERT INTO
      transactions_types
      (
        ttype_id,
        ttype_parent,
        ttype_name,
        ttype_creditdebit,
        ttype_taxed,
        ttype_desc,
        ttype_status,
        ttype_whereshow,
        ttype_value
      )
    VALUES
      (
        15,
        40,
        'Work credit applied to membership',
        'credit',
        0,
        'Credit towards membership fee from volunteering',
        1,
        'customer',
        0.00
      ),
      (
        24,
        40,
        'Membership Receivables',
        'debit',
        0,
        'Amount owed for membership dues',
        1,
        'customer',
        40.00
      ),
      (
        25,
        40,
        'Membership Payment Received',
        'credit',
        0,
        'Amount paid towards membership dues',
        1,
        'customer',
        -40.00
      ),
      (
        40,
        0,
        'Membership',
        '',
        0,
        'Membership Dues',
        1,
        'customer',
        0.00),
      (
        45,
        40,
        'Membership Payment write-off',
        'credit',
        0,
        'Amount of membership dues written off',
        1,
        'customer',
        0.00
      ),
      (
        46,
        40,
        'Gift Membership Received',
        'debit',
        0,
        'Amount contributed for gift memberships',
        1,
        'customer',
        0.00
      )
      
  6. Update the members table to key on membership_types

    We will key to the membership_types table and use that to configure membership parameters instead of storing dues in the members.membr_amt_owed field and using a separate members_type table to keep track of the membership types. Ultimately we will store membership receivables and payments in the transactions table based upon criteria from the membership_types table. In this step, we change the members.membr_amt_owed to members.membership_type_id.

    ALTER TABLE
      members
    CHANGE
      memb_amt_owed membership_type_id TINYINT NULL DEFAULT NULL 
      
  7. Create the membership_type_id table

    Execute the following query in the food cooperative database to generate the membership_type_id table. Then populate that table with values appropriate to your membership types. A definition of the fields and their uses follows the query.

    CREATE TABLE IF NOT EXISTS
      membership_types
      (
      membership_type_id int(11) NOT NULL auto_increment,
      initial_cost float NOT NULL,
      order_cost float NOT NULL,
      annual_cost float NOT NULL,
      membership_class varchar(30) NOT NULL,
      membership_description varchar(255) NOT NULL,
      pending tinyint(4) NOT NULL default '1',
      PRIMARY KEY  (membership_type_id)
      )
      
    membership_type_id: This is the field key and should be unique for each membership type, beginning with "1".
    initial_cost: The amount this membership type must pay in order to join.
    order_cost: The amount this membership type must pay with each order.
    annual_cost: The amount this membership type must pay on an annual basis for membership.
    membership_class: Short description of the membership type (e.g. Producer Member).
    membership_description: Long description of the membership type giving more details. This text is visible on the membership join form. This could include a human-readable description of the fees and conditions associated with this type of membership.
    pending: Set to "0" to make these members able to log in immediately; otherwise set to "1" to make them initially pending.

    Once you have modified the members table to accept membership_type_id and have created and populated the membership_types table to key it with, you will need to do two labor-intensive things:

    • Convert each row of members.membership_type_id to the correct value for the member type. If you previously had differing amounts for the memb_amt_owed then you may be able to do a conversion of those values to the new membership_type_id value.
    • Add any outstanding membership receivables to the transactions table. If members do not have any outstanding membership balance, it will be easiest to leave the membership dues blank, but it would be better (in light of future membership accounting releases) to enter receivable/payment pairs to show the membership payment history more accurately. NOTE: As future members join, the membership form will automatically add the correct receivable to the transactions table.