<?php

class CustomerModel extends Model {
    
    public function 
__construct() {
        
        
$this->mandatoryFields[] = (object) array('name' => 'name''type' => 'notEmpty');
        
        
$this->data['title_show'] = _('Kunde');
        
$this->data['title_new'] = _('Neuen Kunde anlegen');
        
$this->data['title_edit'] = _('Kunden bearbeiten');
        
$this->data['labelTitle'] = _('Anrede');
        
$this->data['labelFirstname'] = _('Vorname');
        
$this->data['labelName'] = _('Name');
        
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$this->data array_merge($this->data$modelAddress->getLabelData());
        
$this->data array_merge($this->data$modelTelephone->getLabelData());
        
$this->data array_merge($this->data$modelEmailAddress->getLabelData());
        
        
$this->data['txtGotoCreateInvoice'] = _('Rechnung erstellen');
        
$this->data['txtGotoCreateQuotation'] = _('Angebot erstellen');
    }
    
    public function 
getById($id) {
        global 
$db;
        
$customer null;
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$sql 'select * from customer where id = '.$db->quote($id);
        
$rows $db->queryFetchAll($sql);
        if (
count($rows)>0) {
            
$customer $rows[0];
            
$customer->address      $modelAddress->getAllById($id'customerId');
            
$customer->telephone    $modelTelephone->getAllById($id'customerId');
            
$customer->emailAddress $modelEmailAddress->getAllById($id'customerId');
        }
        
        if (
count($customer->address) == 0) {
            
$customer->address[]      = $modelAddress->getNew();
        }
        if (
count($customer->telephone) == 0) {
            
$customer->telephone[]    = $modelTelephone->getNew();
        }
        if (
count($customer->emailAddress) == 0) {
            
$customer->emailAddress[] = $modelEmailAddress->getNew();
        }
        
        
$customer->removeAddress = array();
        
$customer->removeTelephone = array();
        
$customer->removeEmailAddress = array();
        
        if (
$customer) {
            
$customer->invalidFields = array();
        }
        
        return 
$customer;
    }
    
    public function 
getByIdShort($id) {
        global 
$db;
        
$customer null;
        
        
$sql 'select id, title, name, firstname from customer where id = '.$db->quote($id);
        
$rows $db->queryFetchAll($sql);
        if (
count($rows)>0) {
            
$customer $rows[0];
        }
        
        return 
$customer;
    }
    
    public function 
getNew() {
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$customer = new stdClass();
        
$customer->id 0;
        
$customer->title '';
        
$customer->firstname '';
        
$customer->name '';
        
        
$customer->address = array();
        
$customer->address[] = $modelAddress->getNew();
        
$customer->removeAddress = array();
        
        
$customer->telephone = array();
        
$customer->telephone[] = $modelTelephone->getNew();
        
$customer->removeTelephone = array();
        
        
$customer->emailAddress = array();
        
$customer->emailAddress[] = $modelEmailAddress->getNew();
        
$customer->removeEmailAddress = array();
        
        
$customer->invalidFields = array();
        
        return 
$customer;
    }
    
    public function 
getNewShort() {
        
$customer = new stdClass();
        
$customer->id 0;
        
$customer->title '';
        
$customer->firstname '';
        
$customer->name '';
        
        return 
$customer;
    }
    
    public function 
getNewFromData($data) {
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$customer = new stdClass();
        
$customer->id = ((int)$data['id']);
        
$customer->title $data['title'];
        
$customer->firstname $data['firstname'];
        
$customer->name $data['name'];
        
        
$customer->address = array();
        
$customer->removeAddress = (isset($data['removeCustomerAddress']) ? $data['removeCustomerAddress'] : array());
        foreach (
$data['customerAddress'] as $aNr => &$address) {
            if (isset(
$data['customerAddress_remove_'.$aNr])) {
                
$customer->removeAddress[] = $address['id'];
                continue;
            } else {
                
$address['customerId'] = $customer->id;
                
$customer->address[] = $modelAddress->getNewFromData($address);
                
                if (isset(
$data['customerAddress_add_'.$aNr])) {
                    
$newAddress $modelAddress->getNew();
                    
$newAddress->customerId $customer->id;
                    
$customer->address[] = $newAddress;
                }
            }
        }
        
$customer->telephone = array();
        
$customer->removeTelephone = (isset($data['removeCustomerTelephone']) ? $data['removeCustomerTelephone'] : array());
        foreach (
$data['customerTelephone'] as $aNr => &$telephone) {
            if (isset(
$data['customerTelephone_remove_'.$aNr])) {
                
$customer->removeTelephone[] = $telephone['id'];
                continue;
            } else {
                
$telephone['customerId'] = $customer->id;
                
$customer->telephone[] = $modelTelephone->getNewFromData($telephone);
                
                if (isset(
$data['customerTelephone_add_'.$aNr])) {
                    
$newTelephone $modelTelephone->getNew();
                    
$newTelephone->customerId $customer->id;
                    
$customer->telephone[] = $newTelephone;
                }
            }
        }
        
$customer->emailAddress = array();
        
$customer->removeEmailAddress = (isset($data['removeCustomerEmailAddress']) ? $data['removeCustomerEmailAddress'] : array());
        foreach (
$data['customerEmailAddress'] as $aNr => &$emailAddress) {
            if (isset(
$data['customerEmailAddress_remove_'.$aNr])) {
                
$customer->removeEmailAddress[] = $emailAddress['id'];
                continue;
            } else {
                
$emailAddress['customerId'] = $customer->id;
                
$customer->emailAddress[] = $modelEmailAddress->getNewFromData($emailAddress);
                
                if (isset(
$data['customerEmailAddress_add_'.$aNr])) {
                    
$newEmailAddress $modelEmailAddress->getNew();
                    
$newEmailAddress->customerId $customer->id;
                    
$customer->emailAddress[] = $newEmailAddress;
                }
            }
        }
        
        if (
count($customer->address) == 0) {
            
$customer->address[] = $modelAddress->getNew();
        }
        if (
count($customer->telephone) == 0) {
            
$customer->telephone[] = $modelTelephone->getNew();
        }
        if (
count($customer->emailAddress) == 0) {
            
$customer->emailAddress[] = $modelEmailAddress->getNew();
        }
        
        
$customer->invalidFields = array();
        
        return 
$customer;
    }
    
    public function 
insert($data) {
        global 
$db;
        
$newCustomerId null;
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$nestedTransaction $db->isTransactionRunning(); # if there's a started transaction, let caller handle transaction and exceptions
        
        
try {
            if (!
$nestedTransaction) {
                
$db->beginTransaction();
            }
            
            
$sql 'insert customer (
                title,
                firstname,
                name
                ) values ('
                
.$db->quote($data['title']).', '
                
.$db->quote($data['firstname']).', '
                
.$db->quote($data['name'])
                .
')';
            
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
            if (
$result) {
                if (
$result->rowCount()>0) {
                    
                    
$newCustomerId $db->lastInsertId();

                    
# create addresses
                    
foreach ($data['customerAddress'] as &$address) {
                        
$address['customerId'] = $newCustomerId;
                        
$modelAddress->insert($address);
                    }
                    
# create telephones
                    
foreach ($data['customerTelephone'] as &$telephone) {
                        
$telephone['customerId'] = $newCustomerId;
                        
$modelTelephone->insert($telephone);
                    }
                    
# create email addresses
                    
foreach ($data['customerEmailAddress'] as &$emailAddress) {
                        
$emailAddress['customerId'] = $newCustomerId;
                        
$modelEmailAddress->insert($emailAddress);
                    }
                }
            }
            
            if (!
$nestedTransaction) {
                
$db->commit();
            }
            
        } catch (
PDOException $e) {
            if (!
$nestedTransaction) {
                
$db->rollBack();
                
$newCustomerId null;
                
$bt debug_backtrace(); $backtraceFlat '['.__CLASS__.'::'.__FUNCTION__.' / line '.__LINE__.' ] [caller: '.$bt[0]['file'].' / line '.$bt[0]['line'].']';
                
Errors::log('sql query failed: '.$e->getMessage().' '.$backtraceFlat);
                if (
DEBUG_SQL) { Errors::log('sql: '.$db->lastSql.' '); }
            } else {
                throw 
$e;
            }
        }
        if (
$newCustomerId) {
            return 
$newCustomerId;
        } else {
            return 
false;
        }
        return 
false;
    }
    
    public function 
update($data) {
        global 
$db;
        
$ret false;
        
$modelAddress = new CustomerAddressModel();
        
$modelTelephone = new CustomerTelephoneModel();
        
$modelEmailAddress = new CustomerEmailAddressModel();
        
        
$nestedTransaction $db->isTransactionRunning(); # if there's a started transaction, let caller handle transaction and exceptions
        
        
try {
            if (!
$nestedTransaction) {
                
$db->beginTransaction();
            }
            
            
$sql 'update customer set '
                
.'title='.$db->quote($data['title']).', '
                
.'firstname='.$db->quote($data['firstname']).', '
                
.'name='.$db->quote($data['name'])
                .
'where id='.$db->quote($data['id']);

            
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
            
            
# update addresses
            
foreach ($data['customerAddress'] as &$address) {
                if (((int)
$address['id'])>0) {
                    
$modelAddress->update($address);
                } else {
                    
# dont insert empty dummy row (violates constraint by customerId 0)
                    
if (((int)$address['customerId']) > 0) {
                        
$modelAddress->insert($address);
                    }
                }
            }
            
# delete removed addresses
            
if (isset($data['removeCustomerAddress'])  &&  count($data['removeCustomerAddress'])) {
                
$addressIdList implode(', '$data['removeCustomerAddress']);
                
$sql "delete from customerAddress where id in (".$addressIdList.")";
                
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
            }
            
            
            
# update telephones
            
foreach ($data['customerTelephone'] as &$telephone) {
                if (((int)
$telephone['id'])>0) {
                    
$modelTelephone->update($telephone);
                } else {
                    
# dont insert empty dummy row (violates constraint by customerId 0)
                    
if (((int)$telephone['customerId']) > 0) {
                        
$modelTelephone->insert($telephone);
                    }
                }
            }
            
# delete removed telephones
            
if (isset($data['removeCustomerTelephone'])  &&  count($data['removeCustomerTelephone'])) {
                
$telephoneIdList implode(', '$data['removeCustomerTelephone']);
                
$sql "delete from customerTelephone where id in (".$telephoneIdList.")";
                
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
            }
            
            
            
# update email addresses
            
foreach ($data['customerEmailAddress'] as &$emailAddress) {
                if (((int)
$emailAddress['id'])>0) {
                    
$modelEmailAddress->update($emailAddress);
                } else {
                    
# dont insert empty dummy row (violates constraint by customerId 0)
                    
if (((int)$emailAddress['customerId']) > 0) {
                        
$modelEmailAddress->insert($emailAddress);
                    }
                }
            }
            
# delete removed email addresses
            
if (isset($data['removeCustomerEmailAddress'])  &&  count($data['removeCustomerEmailAddress'])) {
                
$emailAddressIdList implode(', '$data['removeCustomerEmailAddress']);
                
$sql "delete from customerEmailAddress where id in (".$emailAddressIdList.")";
                
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
            }
            
            
            if (!
$nestedTransaction) {
                
$db->commit();
                
$ret true;
            }
            
        } catch (
PDOException $e) {
            if (!
$nestedTransaction) {
                
$db->rollBack();
                
$ret false;
                
$bt debug_backtrace(); $backtraceFlat '['.__CLASS__.'::'.__FUNCTION__.' / line '.__LINE__.' ] [caller: '.$bt[0]['file'].' / line '.$bt[0]['line'].']';
                
Errors::log('sql query failed: '.$e->getMessage().' '.$backtraceFlat);
                if (
DEBUG_SQL) { Errors::log('sql: '.$db->lastSql.' '); }
            } else {
                throw 
$e;
            }
        }
        
        return 
$ret;
    }
    
    public function 
delete($customerId) {
        global 
$db;
        
        
$sql 'delete from customer where id = '.$db->quote($customerId);
        
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
        if (
$result) {
            if (
$result->rowCount()>0) {
                return 
true;
            }
        }
        return 
false;
    }
    
    public static function 
hasSystem($customerId) {
        global 
$db;
        
        
$sql 'select count(*) as count from system where customerId = '.$db->quote($customerId);
        
$result $db->query($sql, ($db->isTransactionRunning() ? false true) );
        
$rows $db->queryFetchAll($sql);
        if (
count($rows)>0) {
            if (
$rows[0]->count 0) {
                return 
true;
            }
        }
        return 
false;
    }
}