loadMe(); // Set audit fields $invoice->create_by = $me->id; $invoice->edit_by = $me->id; $invoice->create = time(); $invoice->edit = time(); // Set invoice fields foreach($data as $field => $value) { if(property_exists($invoice, $field) && $field != 'id') { $invoice->$field = $value; } } // Set defaults if (!$invoice->billing_type) { $invoice->billing_type = 'invoice'; } if (!$invoice->billing_delivery) { $invoice->billing_delivery = 'email'; } if (!$invoice->total) { $invoice->total = 0; } if (!$invoice->total_gross) { $invoice->total_gross = 0; } if (!$invoice->vatgroup_id) { $invoice->vatgroup_id = 1; // Default VAT group } if (!$invoice->owner_id) { $invoice->owner_id = 0; } if (!$invoice->billingaddress_id) { $invoice->billingaddress_id = 0; } if (!$invoice->customer_number) { $invoice->customer_number = 0; } if ($invoice->save()) { return $invoice->id; } return false; } public static function getNextInvoiceNumber() { $last_invoice_num = self::getLastInvoiceNumber(); if(!$last_invoice_num) { return "MRN".date("Y")."-X000001"; } $year_part = 0; $num_part = 0; $m = []; if(preg_match('/^MRN(\d+)-X(\d+)$/', $last_invoice_num, $m)) { if(array_key_exists(1, $m)) { $year_part = $m[1]; if(array_key_exists(2, $m)) { $num_part = $m[2]; } } } if(!$year_part || !$num_part) { return "MRN".date("Y")."-X000001"; } if(date("Y") == $year_part) { $new_year_part = $year_part; $new_num_part = $num_part + 1; } else { $new_year_part = date("Y"); $new_num_part = 1; } $new_invoice_num = "MRN$new_year_part-X".str_pad($new_num_part,"6", "0", STR_PAD_LEFT); return $new_invoice_num; } public static function getLastInvoiceNumber() { $last_invoice = self::getLast(["invoice_number" => true]); if(!$last_invoice || !$last_invoice->invoice_number) { return false; } return $last_invoice->invoice_number; } public static function getAll($filter = [], $limit = null, $offset = 0, $order = ["key" => null]) { $items = []; $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); $sql = "SELECT ManualInvoice.* FROM ManualInvoice WHERE $where"; if ($order['key'] !== null) { $orderDir = isset($order['order']) ? $order['order'] : 'ASC'; $sql .= " ORDER BY " . $order['key'] . " " . $orderDir; } else { $sql .= " ORDER BY invoice_number"; } if($limit !== null) { $sql .= " LIMIT " . intval($offset) . ", " . intval($limit); } $res = $db->query($sql); if($db->num_rows($res)) { while($data = $db->fetch_object($res)) { $items[] = new ManualInvoice($data); } } return $items; } public static function getFirst($filter) { $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); $sql = "SELECT ManualInvoice.* FROM ManualInvoice WHERE $where ORDER BY invoice_number LIMIT 1"; $res = $db->query($sql); if($db->num_rows($res)) { $data = $db->fetch_object($res); $item = new ManualInvoice($data); if($item->id) { return $item; } else { return null; } } return null; } public static function getLast($filter) { $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); $sql = "SELECT ManualInvoice.* FROM ManualInvoice WHERE $where ORDER BY invoice_number DESC LIMIT 1"; mfLoghandler::singleton()->debug($sql); $res = $db->query($sql); if($db->num_rows($res)) { $data = $db->fetch_object($res); $item = new ManualInvoice($data); if($item->id) { return $item; } else { return null; } } return null; } public static function count($filter = []) { $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); $sql = "SELECT COUNT(*) as cnt FROM ManualInvoice WHERE $where"; mfLoghandler::singleton()->debug($sql); $res = $db->query($sql); if($db->num_rows($res)) { $data = $db->fetch_object($res); return $data->cnt; } return 0; } public static function search($filter, $limit = false, $order = false) { $items = []; if(!$order) { $order = "invoice_number ASC"; } $db = FronkDB::singleton(); $where = self::getSqlFilter($filter); $sql = "SELECT ManualInvoice.* FROM ManualInvoice WHERE $where ORDER BY $order"; if(is_array($limit) && count($limit)) { if(is_numeric($limit['start']) && is_numeric($limit['count'])) { $sql .= " LIMIT ".$limit['start'].", ".$limit['count']; } elseif(is_numeric($limit['count'])) { $sql .= " LIMIT ".$limit['count']; } } mfLoghandler::singleton()->debug($sql); $res = $db->query($sql); if($db->num_rows($res)) { while($data = $db->fetch_object($res)) { $items[$data->id] = new ManualInvoice($data); } } return $items; } private static function getSqlFilter($filter) { $where = "1=1 "; $db = FronkDB::singleton(); if(array_key_exists("id", $filter)) { $id = $filter['id']; if(is_numeric($id)) { $where .= " AND ManualInvoice.id like '%$id%'"; } } if(array_key_exists("invoice_number", $filter)) { $invoice_number = $filter['invoice_number']; if($invoice_number === true) { $where .= " AND ManualInvoice.invoice_number IS NOT NULL AND ManualInvoice.invoice_number <> ''"; } elseif($invoice_number) { $invoice_number = $db->escape($invoice_number); $where .= " AND ManualInvoice.invoice_number='$invoice_number'"; } elseif($invoice_number === null || $invoice_number === false) { $where .= " AND ManualInvoice.invoice_number IS NULL"; } } if(array_key_exists("invoice_number%", $filter)) { $invoice_number = $filter['invoice_number%']; if($invoice_number) { $where .= " AND ManualInvoice.invoice_number LIKE '%$invoice_number%'"; } } if(array_key_exists("invoice_date", $filter)) { $invoice_date = $filter['invoice_date']; if($invoice_date) { $where .= " AND ManualInvoice.invoice_date='$invoice_date'"; } elseif($invoice_date === null || $invoice_date === false) { $where .= " AND ManualInvoice.invoice_date IS NULL"; } } if(array_key_exists("invoice_date>=", $filter)) { $invoice_date = $db->escape($filter['invoice_date>=']); if($invoice_date) { $where .= " AND ManualInvoice.invoice_date >= '$invoice_date'"; } } if(array_key_exists("invoice_date<=", $filter)) { $invoice_date = $db->escape($filter['invoice_date<=']); if($invoice_date) { $where .= " AND ManualInvoice.invoice_date <= '$invoice_date'"; } } if(array_key_exists("owner_id", $filter)) { $owner_id = $filter['owner_id']; if(is_numeric($owner_id)) { $where .= " AND ManualInvoice.owner_id=$owner_id"; } } if(array_key_exists("billingaddress_id", $filter)) { $billingaddress_id = $filter['billingaddress_id']; if(is_numeric($billingaddress_id)) { $where .= " AND ManualInvoice.billingaddress_id=$billingaddress_id"; } } if(array_key_exists("customer_number", $filter)) { $customer_number = $filter['customer_number']; if(is_numeric($customer_number)) { $where .= " AND ManualInvoice.customer_number LIKE $customer_number"; } } if(array_key_exists("billing_type", $filter)) { $billing_type = $db->escape($filter['billing_type']); if($billing_type) { $where .= " AND ManualInvoice.billing_type LIKE '$billing_type'"; } } if(array_key_exists("billing_delivery", $filter)) { $billing_delivery = $db->escape($filter['billing_delivery']); if($billing_delivery) { $where .= " AND ManualInvoice.billing_delivery LIKE '$billing_delivery'"; } } if(array_key_exists("add-where", $filter)) { $where .= " ".$filter['add-where']; } return $where; } public static function get($id) { return self::getFirst(["id" => $id]); } public static function update($data) { if (!isset($data['id'])) { return 0; } $invoice = new ManualInvoice($data['id']); if (!$invoice->id) { return 0; } $me = new User(); $me->loadMe(); // Set audit fields $invoice->edit_by = $me->id; $invoice->edit = time(); // Update fields foreach($data as $field => $value) { if(property_exists($invoice, $field) && $field != 'id' && $field != 'create' && $field != 'create_by') { $invoice->$field = $value; } } if ($invoice->save()) { return 1; } return 0; } public static function delete($id) { $invoice = new ManualInvoice($id); if (!$invoice->id) { return 0; } // Delete positions first $positions = ManualInvoicepositionModel::search(['manualinvoice_id' => $id]); foreach ($positions as $pos) { $pos->delete(); } // Delete invoice if ($invoice->delete()) { return 1; } return 0; } }