For the attribute table, I meant something similar to the sys_prefs table in FA, but linked to each of the main entities in the payroll. If you have a pay items table similar in purpose to the FA items table, the pay item table itself would not have any columns specific to any one country but have a table linked to it to contain all the values of what would be country specific columns in the pay item table. I don't think you'd include the type and length of each attribute in the attribute table, unlike the FA sys_prefs table, but should probably have a separate attributes index table that defined all the possible attributes, their types and lengths and scope.

The payroll pay item attribute table would then just have the pay item id, the attribute index id, and the value specific to this pay item.

For example, the pay item table would have a code, description, a link to an FA expense account and fields to declare how the pay item is to be calculated. A pay item record for a salary would have a calculation method field that linked the pay item to the salary calculation function, and a separate tax pay item would link the item to the tax calculation function. But there are other attributes linked to a pay item that would have to be associated with specific countries, such as a tax category to indicate how that pay item is to be reported for tax, or perhaps how that pay item might be included in the total from which another pay item is calculated. Those types of attributes should not be columns within the pay item table, but perhaps each value stored as a separate record in a 'pay item attributes' table, linked to the pay item.

It then becomes possible to easily add processing for new countries whilst not upsetting the processing for countries already defined. You'd need attributes tables linked to each of the main entities in the payroll: the company, employees, pay items and payslip (pay check) records.

Adding a new country to the framework then means simply adding the new attributes, calculation functions and country specific reports. Hopefully the core tables would not need changing, but you might need to add country specific reference tables: the UK needs tiered National Insurance rate tables as well as tiered tax tables, and different countries quite often have different fields for each tax tier. For Australia there are two percentage rates involved in the tax calculation. For UK, you have to flag which tier is the basic rate tax, and so on.

I think you do need a separate table for payslips and payslip items, just as FA has sales order and sales order details, and the GL entries are generated from them. The payslip and payslip items tables also need their own attribute tables as some countries require values to be carried forward from pay to pay.

I have followed this design for a PC payroll system that is sold in Australia, New Zealand, United Kingdom, and several Pacific islands. It's worked quite well so far and it's relatively easy for me to extend the software for new countries. I had considered adding a payroll module to FA myself based on the same design, but I am a bit tied up with support and enhancements for that other payroll and don't have much time left.

You will need to allow for different groups of employees being paid on different days on different pay cycles.

In general you should avoid data entry columns specific to any type of pay such as salary or commission. Your database structure should support the user definition of pay items similar to inventory items, and have a pay cart built using those pay items.

When defining your database structures avoid including any columns that are specific to any one country.  Instead, you could create attribute tables linked to the core common data tables. The basic calculated payslip items should only need a quantity column, a rate and a calculated cash amount.

Avoid holding any accumulated totals in any tables. Always output totals by accumulating the core calculated payslip items. Using attributes linked to the pay items to define report categories it makes it relatively easy to create reports for different countries requirements.

I hope I have not been too discouraging.

To save people's time, I got a better solution that works (after I had fixed some missing join columns in the customer and branch tables!), using routines in the sales_order_ui include:

    $entry = new Cart(ST_SALESINVOICE, 0, true);
    get_customer_details_to_order($entry, $customer_id, $branch_id);
    add_to_order($entry, $item_code, 1, $gross, 0, $item_title);
    $entry->cust_ref = $ref;
    $taxes = $entry->get_taxes($shipping);
    $entry->write(0);

When I had created the customer and branch records prior to creating the invoice, I had missed location, and shipper id, both of which are needed in order to re-read the sales order when it generates delivery notes and invoices.

When I have the customer payment allocation working, I'll submit the module to Joe in case anyone else finds it useful.

I'm struggling with an add-on I'm writing to import transactions from paypal. I have a version working fine creating bank deposits as cash sales, but what I'd really like to do is create/update customer records, create direct invoices, and then allocate payments. The reason being that many customers might start with a paypal payment but later get invoiced directly for other work. Having all their details already in the system makes it less work later.

I have tried stepping though the cart class as a direct invoice is entered in the screen, and as far as I can see the following code might be the minimum required:

    $entry = new Cart(ST_SALESINVOICE, 0);
    $entry->set_customer($customer_id, $company, $currency, 0, -1, 0);
    $myrow = get_sales_type($paypal_sales_type_id);
    $entry->set_sales_type($myrow['id'], $myrow['sales_type'],
        $myrow['tax_included'], $myrow['factor']);
    $entry->add_to_cart(0, $item_code, 1, $gross, 0, 0, $item_title, 0, 0, 0);
    $taxes = $entry->get_taxes($shipping);
    $entry->write(1);

There is a value in every variable, and the customer records have been set up, and I've created direct invoices through FA using those generated customers.

But when I run my import I get an error for every transaction:

You have missing or invalid sales document in database (type:30, number:x).

Is anyone able to help?

Many thanks
Alastair