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.