If I try to save by explicitly creating a new ActivityInvoiceMap (tried this as it does not seem to be doing it "magically")
excerpt from InvoicesController.php:
$activity_invoice_map = new ActivityInvoiceMap();
$activity_detail = Activities::findFirstByactivity_id($invoice_rows[$n]['activity_id']);
$activity_detail->activity_state = 'Billed';
if (!$activity_detail->save()) {
foreach ($activity_detail->getMessages() as $message) {
$this->flash->error($message);
}
}
and further down:
$invoice = new Invoices();
$activity_invoice_map = new ActivityInvoiceMap();
$invoice->client_id = $details['client_id'];
$invoice->invoice_number = $details['invoice_number'];
$invoice->invoice_description = 'Invoice '.$details['invoice_number'].' - '.date('M j Y');
$invoice->invoice_created = date('Y-m-d H:i:s');
$invoice->invoice_submitted = date('Y-m-d H:i:s');
$invoice->invoice_edited = date('Y-m-d H:i:s');
$invoice->invoice_status = 'Submitted';
$invoice->invoice_due = date('Y-m-d H:i:s', strtotime((date('Y-m-d H:i:s').'+ 5 days')) );
$invoice->invoice_amount = preg_replace("/([^0-9\\.])/i", "", ($details['invoice_detail_total_billable']));
if (!$invoice->create()) {
foreach ($invoice->getMessages() as $message) {
$this->flash->error($message);
}
If does not like that - it says it can't find the model. I tried using save(), update(), create() as per docs to no effect.
The schema was designed to be beyond obvious, e.g. in invoices there's invoice_id and in activities there's activity_id, in the map table it's referred to as exactly the same, activity_id and invoice_id. It's an old schema. Here are the models, a lot of this is just standard generation from Phalcon Tools.
ActivityInvoiceMap.php
<?php
namespace App\Models;
class ActivityInvoiceMap extends \Phalcon\Mvc\Model
{
/**
*
* @var integer
*/
public $activity_invoice_map;
/**
*
* @var integer
*/
public $activity_id;
/**
*
* @var integer
*/
public $invoice_id;
/**
* Initialize method for model.
*/
public function initialize()
{
$this->belongsTo('activity_id', 'Activities', 'activity_id', array('alias' => 'Activities'));
$this->belongsTo('invoice_id', 'Invoices', 'invoice_id', array('alias' => 'Invoices'));
}
/**
* Returns table name mapped in the model.
*
* @return string
*/
public function getSource()
{
return 'activity_invoice_map';
}
/**
* Allows to query a set of records that match the specified conditions
*
* @param mixed $parameters
* @return ActivityInvoiceMap[]
*/
public static function find($parameters = null)
{
return parent::find($parameters);
}
/**
* Allows to query the first record that match the specified conditions
*
* @param mixed $parameters
* @return ActivityInvoiceMap
*/
public static function findFirst($parameters = null)
{
return parent::findFirst($parameters);
}
}
Invoices.php
<?php
namespace App\Models;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset\Simple as Resultset;
use Phalcon\Mvc\Model\Manager as ModelsManager;
use App\Models\Activities;
use App\Models\ActivityInvoiceMap;
use App\Models\Clients;
use App\Models\Projects;
class Invoices extends \Phalcon\Mvc\Model
{
/**
*
* @var integer
*/
public $invoice_id;
/**
*
* @var integer
*/
public $client_id;
/**
*
* @var string
*/
public $invoice_number;
/**
*
* @var string
*/
public $invoice_description;
/**
*
* @var string
*/
public $invoice_created;
/**
*
* @var string
*/
public $invoice_edited;
/**
*
* @var string
*/
public $invoice_submitted;
/**
*
* @var string
*/
public $invoice_status;
/**
*
* @var string
*/
public $invoice_paid;
/**
*
* @var string
*/
public $invoice_due;
/**
*
* @var double
*/
public $invoice_amount;
/**
* Initialize method for model.
*/
public function initialize()
{
$this->hasMany('invoice_id', 'ActivityInvoiceMap', 'invoice_id', array('alias' => 'ActivityInvoiceMap'));
$this->belongsTo('client_id', 'Clients', 'client_id', array('alias' => 'Clients'));
}
/**
* Returns table name mapped in the model.
*
* @return string
*/
public function getSource()
{
return 'invoices';
}
/**
* Allows to query a set of records that match the specified conditions
*
* @param mixed $parameters
* @return Invoices[]
*/
public static function find($parameters = null)
{
return parent::find($parameters);
}
/**
* Allows to query the first record that match the specified conditions
*
* @param mixed $parameters
* @return Invoices
*/
public static function findFirst($parameters = null)
{
return parent::findFirst($parameters);
}
public static function getHourlyBilling($client_id, $params = null)
{
if (is_numeric($client_id)) {
$sql = 'select client_companyname, client_contact_address, client_contact_email, client_id, activity_id, project_id, project_name, project_currency, activity_description, activity_hourly, activity_start,
activity_end, time, round((time * activity_hourly),2) as billable from (
select c.client_companyname as client_companyname, c.client_contact_email as client_contact_email, c.client_id as client_id, activity_id, project_id, p.project_name as project_name,
p.project_currency as project_currency, activity_description, activity_hourly,
concat_ws(\'<br />\',`client_contact`,`client_billing_street`,`client_billing_city`,`client_billing_state`,`client_billing_postcode`) as client_contact_address,
convert_tz(activity_start,\'UTC\',\'America/New_York\') as activity_start, convert_tz(activity_end,\'UTC\',\'America/New_York\') as activity_end,
(hour(timediff(`activity_end`,`activity_start`))+round((ceil(minute(timediff(`activity_end`,`activity_start`)))*0.016666667),2)) as time
from activities a
join projects p using (project_id)
join clients c using (client_id)
where activity_state = "Unbilled" and activity_type not like "Fixed" and activity_type not like "Subcontractor" and activity_start is not null and activity_end is not null
and c.client_id = '.$client_id.' ) sq1 where time > 0 order by sq1.activity_start';
$invoice = new Invoices();
$unbilled = (new Resultset(null, $invoice, $invoice->getReadConnection()->query($sql,$params)))->toArray();
return $unbilled;
} else {
return false;
}
}
public static function getFixedCostBilling($client_id, $params = null)
{
if (is_numeric($client_id))
{
$invoice = new Invoices();
$sql = 'select c.client_companyname, c.client_id, c.client_contact_email, activity_id, project_id, p.project_name, p.project_currency, activity_description, activity_fixed_amount as billable,
concat_ws(\'<br />\',`client_contact`,`client_billing_street`,`client_billing_city`,`client_billing_state`,`client_billing_postcode`) as client_contact_address
from activities a
join projects p using (project_id)
join clients c using (client_id)
where activity_state = "Unbilled" and activity_type like "Fixed" and activity_type not like "Subcontractor" and activity_fixed_amount != 0 and c.client_id='.$client_id.' order by activity_start';
$unbilled = (new Resultset(null, $invoice, $invoice->getReadConnection()->query($sql,$params)))->toArray();
return $unbilled;
}
else
{
return false;
}
}
public static function getLast()
{
$invoice = new Invoices();
$sql = 'select max(invoice_id) as max from invoices';
$params = new \StdClass();
$lastId = (new Resultset(null, $invoice, $invoice->getReadConnection()->query($sql,$params)))->toArray();
return $lastId;
}
}