Using Counter in Company Table

Hi, we have a table Company with COmpany Information, and some fields, for example: InvoiceNumber.

And then we have a simple table created Invoices.

We need to Get the number indicated in CompanyInformation and Verify if this not exists in table Invoices, and then, assign to Invoice. Then, when the invoice is saved, verify that another computer/client has not used this number, and if exists, then go to the next number, and then update the Comapny.InvoiceNumber.

I think it’s the best way to avoid having gaps in numbers.

Can you provide a simple project with 2 Screen that make’s this operation?

Hi Ivan,
Let me clarify something about your task.

> when the invoice is saved, verify that another computer/client has not used this number, and if exists, then go to the next number

Does it mean that when a new Invoice editor is opened, it shows a number to the user, but when it is saved, the number can be changed? Don’t you think that it is confusing and can lead to user errors, like if the user writes down the number and tells it to someone, and the number is actually wrong?
Maybe better not to show the number before saving at all?

Yes, is Good Solution to hide when is new, and show when is saved.

Have you any other idea to do it there?

Hi Ivan,
For me it is more feasible to generate the invoice number only when the user proceeds to finalize the document, not before. As is as Konstantin says, it is very confusing to see a number on screen and then it turns out that another is stored.
In addition you avoid being verifying if it was used or not by another user.

It’s ok for me, is good solution.

konstantin, have any similar project or example, or it’s possible to make’it ?

I think it’s a good example for many developers.

Thanks!

The simplest way to generate uniqie numbers for documents is using UniqueNumbersAPI in a BeforeInsertEntityListener.
For example:


@Component("numbering_InvoiceEntityListener")
public class InvoiceEntityListener implements BeforeInsertEntityListener<Invoice> {

    @Inject
    private UniqueNumbersAPI uniqueNumbers;

    @Override
    public void onBeforeInsert(Invoice entity) {
        entity.setNumber(String.valueOf(uniqueNumbers.getNextNumber("invoice")));
    }
}

You can also disable the number field for a not saved invoice:


public class InvoiceEdit extends AbstractEditor<Invoice> {

    @Named("fieldGroup.number")
    protected TextField numberField;

    @Override
    protected void postInit() {
        if (PersistenceHelper.isNew(getItem())) {
            numberField.setEditable(false);
        }
    }
}

With this approach, there is still a small possibility for gaps in numbers - they can appear if the document is not committed successfully after acquiring a number in entity listener. If it is not acceptable, the mechanism of generating numbers should be completely different (based on a pool of numbers), and it will sometimes generate non-sequential numbers.

Konstantin, for invoice number is not good solution, is best solution to have a Company Counters table.

For me UniqueNumbersAPI is Good for Lines of the Invoice, but you can leave the user to desire what Sequencial of numbers they needs. For example Start Number 16000 for year 2016, and another customer starts with number 1 each year.

Inthis line, how can i get the number of the company related with the new invoice, then when i save, see if not exists, and if exists sum++ to their number and then set value of latest number used on company table?

Thanks!

Ivan,
Please create a small project with your entities and screens, and attach it here (Alt+/, “zipProject” in Studio).

Hi i’ve attached a smallest project very simple:

Table Company
Table Invoice

I need, when i create a new Invoice, set InvoiceNumber, with next number of InvoicesCounter in table Company, and verify that number not exists with another invoice.

Maybe, in Listenner BeforeInsert.

And then, when exists only one company, i need on initnewitem, to see how many company exists, and if only one, set this in company automatically.

Thanks!!

InvoicingNumber.zip (31.6K)

setnumber

createcompany

> And then, when exists only one company, i need on initnewitem, to see how many company exists, and if only one, set this in company automatically.

Set a company in a new invoice if there is only one company?

yes, when only exists One Company, set this automatically on Create new Invoice.
When exists two or more, it’s mandatory to select manual their company.

So the implementation is basically the same.
The BeforeInsertEntityListener is used for assigning the next invoice number retrieved from Company:


@Component("invoicingnumber_InvoiceEntityListener")
public class InvoiceEntityListener implements BeforeInsertEntityListener<Invoice> {

    @Inject
    private Persistence persistence;

    @Override
    public void onBeforeInsert(Invoice entity) {
        // check if company is set
        Company company = entity.getCompany();
        if (company == null)
            throw new RuntimeException("Company is not set");

        // get managed instance of Company to update it with the next invoice number
        company = persistence.getEntityManager().reloadNN(company);
        Integer count = company.getInvoiceCount();
        count += 1;
        // save new count to invoice and company
        entity.setNumber(String.valueOf(count));
        company.setInvoiceCount(count);
    }
}

InvoiceEdit selects a company if there is one, and sets number to “not assigned” for successful validation of mandatory attribute:


public class InvoiceEdit extends AbstractEditor<Invoice> {

    @Inject
    private DataManager dataManager;

    @Override
    protected void initNewItem(Invoice item) {
        List<Company> companies = dataManager.loadList(
                LoadContext.create(Company.class).setQuery(
                        LoadContext.createQuery("select c from invoicingnumber$Company c")));
        if (companies.size() == 1) {
            item.setCompany(companies.get(0));
        }
        item.setNumber("not assigned");
    }
}

See also the attached project.

InvoicingNumber.zip (35.3K)