Save daily summary

At last, the sample application will complete in this section.

Modify the application to save the total of sales and payment on the day to daily_summaries table at the same time as saving the invoice.

Mechanism

To save the daily summary, add the amount if the invoice is inserted, and subtract the amount if the invoice is deleted.

However, in the case of updating the invoice, it is necessary to calculate increase / decrease amount. There are several way to calculate it. In this case, we calculate it with handlers used for increasing or decreasing stock.

Calculate increase / decrease amount

We will hold the increase / decrease amount in InvoiceAmount instance. Add onStart method to InvoiceItemSaveHandler, and do new in it. And call increment on onSaveRow, call decrement on onDeleteRow.

class InvoiceItemSaveHandler
{
    public function onStart()
    {
        $this->amount = new InvoiceAmount;
    }

    public function onSaveRow(InvoiceItem $row)
    {
        $this->amount->increment($row);
        // (omitted)
    }

    public function onDeleteRow(InvoiceItem $row)
    {
        $this->amount->decrement($row);
        // (omitted)
    }

Now $this->amount will hold increase / decrease amount.

Save daily summary

Add onEnd method which saves daily summary. Modify the constructor to receive the date, because it is necessary to save daily summary.

class InvoiceItemSaveHandler
{
    // (omitted)

    private $date;

    public function __construct($date)
    {
        $this->date = $date;
    }

    public function onEnd()
    {
        // Get the server cursor of daily summaries
        $it = DailySummary::index(0)->keyValue($this->date)->serverCursor();
        if ($it->valid()) {
            // Update if the record exists
            $daily = $it->current();
            $daily->sum($this->amount);
            $it->update($daily);
        } else {
            // Insert if the record does not exist
            $daily = new DailySummary(['date' => $this->date]);
            $daily->sum($this->amount);
            $it->insert($daily);
        }
        // Reset keyValue etc.
        DailySummary::resetQuery();
        Stock::resetQuery();
    }
}

Call handlers

Finally, call onStart and onEnd in save and delete in Invoice.

class Invoice extends Model
{
    public function save($options = 0, $forceInsert = false)
    {
        InvoiceItem::$handler = new InvoiceItemSaveHandler($this->date);
        // Start calculating daily summary
        InvoiceItem::$handler->onStart();

        // (omitted)

        // Save daily summary
        InvoiceItem::$handler->onEnd();
    }

    public function delete($options = null)
    {
        InvoiceItem::$handler = new InvoiceItemSaveHandler($this->date);
        // Start calculating daily summary
        InvoiceItem::$handler->onStart();

        // (omitted)

        // Save daily summary
        InvoiceItem::$handler->onEnd();
    }

Now the sample application model is complete.

The source code of this sample application can be downloaded from GitHub Gist.

  1. Calculate and save sales invoices
  2. Use models