/**
  * @author KienNN
  * @param \Accounting\Model\Transaction $item
  * Từ transaction tìm lại hợp đồng
  * Tính toán tỉ lệ ăn chia với từng nhân viên [employeeId => amount]
  *     + nếu đã tồn tại payment (salemanId + transactionId) thì update lại thông tin cho payment
  *     + nếu không thì tạo mới payment
  *     Xóa đi những payment ko dc tính
  */
 public function recalculatePayment($item)
 {
     if (!$item->getId() || !$item->getAmount() || !$item->getItemId() || $item->getItemType() != \Accounting\Model\Transaction::ITEM_TYPE_CRM_CONTRACT || !in_array($item->getStatus(), [\Accounting\Model\Transaction::STATUS_ACCOUNTING, \Accounting\Model\Transaction::STATUS_PAYMENT])) {
         return null;
     }
     // lấy ra các sản phẩm trong hợp đồng
     $product = new \Crm\Model\Contract\Product();
     $product->setContractId($item->getItemId());
     $productMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\ProductMapper');
     $products = $productMapper->fetchAll($product);
     // lấy commission
     $commission = new \Crm\Model\Contract\Commission();
     $commission->setContractId($item->getItemId());
     $commissionMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\CommissionMapper');
     $commissions = $commissionMapper->fetchAll($commission);
     // lấy ra các payment cũ của transaction
     $select = $this->getDbSql()->select(['p' => \Crm\Model\Contract\PaymentMapper::TABLE_NAME]);
     $select->join(['e' => \Hrm\Model\EmployeeMapper::TABLE_NAME], 'e.userId=p.salemanId', ['employeeId' => 'id']);
     $select->where(['p.transactionId' => $item->getId()]);
     $rowPays = $this->getDbAdapter()->query($this->getDbSql()->buildSqlString($select), Adapter::QUERY_MODE_EXECUTE);
     $paymentToDeletes = [];
     if ($rowPays->count()) {
         foreach ($rowPays->toArray() as $rowPay) {
             $paymentToDeletes[$rowPay['employeeId']] = new \Crm\Model\Contract\Payment($rowPay);
         }
     }
     // lấy ra tài khoản kế toán của phiếu thu
     $select = $this->getDbSql()->select(['ti' => \Accounting\Model\Transaction\ItemMapper::TABLE_NAME]);
     $select->where(['ti.transactionId' => $item->getId()]);
     $select->limit(1);
     $row = $this->getDbAdapter()->query($this->getDbSql()->buildSqlString($select), Adapter::QUERY_MODE_EXECUTE);
     $row = (array) $row->current();
     $accountingAccountId = null;
     if ($row['debitAccountId']) {
         $accountingAccountId = $row['debitAccountId'];
     } elseif ($row['creditAccountId']) {
         $accountingAccountId = $row['creditAccountId'];
     }
     $accountingAccount = new \Accounting\Model\Account();
     $accountingAccount->setId($accountingAccountId);
     $accountingAccountMapper = $this->getServiceLocator()->get('\\Accounting\\Model\\AccountMapper');
     $accountingAccountMapper->get($accountingAccount);
     // tính toán ra số tiền cho từng nhân viên
     $paymentAmounts = \Crm\Model\Contract\Payment::breakToCommission($item->getAmount(), $products, $commissions);
     $employeeMapper = $this->getServiceLocator()->get('\\Hrm\\Model\\EmployeeMapper');
     $paymentMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\PaymentMapper');
     foreach ($paymentAmounts as $employeeId => $amount) {
         // lấy ra user của employee
         $employee = new \Hrm\Model\Employee();
         $employee->setId($employeeId);
         $employeeMapper->get($employee);
         if ($employee->getUserId()) {
             $payment = new \Crm\Model\Contract\Payment();
             $payment->setTransactionId($item->getId());
             $payment->setSalemanId($employee->getUserId());
             if ($paymentMapper->isExistedInTransaction($payment)) {
                 /** nếu payment đã tồn tại chỉ update lại amount */
                 $payment->setAmount($amount);
                 $paymentMapper->save($payment);
                 unset($paymentToDeletes[$employeeId]);
             } else {
                 /** nếu payment chưa tồn tại thì tạo mới */
                 $payment->setAmount($amount);
                 $payment->setAccountingAccountId($accountingAccountId);
                 $payment->setDescription($item->getDescription());
                 $payment->setCompanyId($employee->getCompanyId());
                 $payment->setDepartmentId($employee->getDepartmentId());
                 $payment->setContractId($item->getItemId());
                 if ($accountingAccount->getType() == \Accounting\Model\Account::TYPE_CASH) {
                     $payment->setType(\Crm\Model\Contract\Payment::TYPE_CASH);
                 } else {
                     $payment->setType(\Crm\Model\Contract\Payment::TYPE_MONEY_TRANSFER);
                 }
                 $payment->setStatus(\Crm\Model\Contract\Payment::STATUS_CHECKED);
                 $payment->setCheckedById($item->getAccountingById());
                 $payment->setCheckedDate($item->getApplyDate());
                 $payment->setCheckedDateTime($item->getAccountingDateTime());
                 $payment->setCreatedById($item->getAccountingById());
                 $payment->setCreatedDateTime($item->getAccountingDateTime());
                 $paymentMapper->save($payment);
             }
         }
     }
     /** Xóa các payment thừa */
     if (count($paymentToDeletes)) {
         foreach ($paymentToDeletes as $payment) {
             $delete = $this->getDbSql()->delete(\Crm\Model\Contract\PaymentMapper::TABLE_NAME);
             $delete->where(['id' => $payment->getId()]);
             $this->getDbAdapter()->query($this->getDbSql()->buildSqlString($delete), Adapter::QUERY_MODE_EXECUTE);
         }
     }
 }
 /**
  * Chỉ rà soát trong 1 khoảng thời gian nhất định
  * Rà soát các transaction trong thời gian quy định
  * Tình toán ra commission theo từng nhân viên
  * Xóa các payment có transactionId=transaction.id
  * Tạo mới payment
  *
  */
 public function recalculatepaymentAction()
 {
     $fromDate = '2015-08-01';
     $transactionId = $this->getRequest()->getQuery('transactionId');
     $dbAdapter = $this->getServiceLocator()->get('dbAdapter');
     $dbSql = $this->getServiceLocator()->get('dbSql');
     $select = $dbSql->select(['t' => \Accounting\Model\TransactionMapper::TABLE_NAME]);
     $select->join(['ti' => \Accounting\Model\Transaction\ItemMapper::TABLE_NAME], 't.id=ti.transactionId', ['accountingAccountId' => new Expression('IFNULL(ti.creditAccountId, ti.debitAccountId)')]);
     $select->where(['createdDate >= ?' => $fromDate]);
     if ($transactionId) {
         $select->where(['t.id' => $transactionId]);
     }
     $query = $dbSql->buildSqlString($select);
     //echo $query;die;
     $rows = $dbAdapter->query($query, Adapter::QUERY_MODE_EXECUTE);
     $commissionMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\CommissionMapper');
     $productMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\ProductMapper');
     $employeeMapper = $this->getServiceLocator()->get('\\Hrm\\Model\\EmployeeMapper');
     $paymentMapper = $this->getServiceLocator()->get('\\Crm\\Model\\Contract\\PaymentMapper');
     $accountingAccountMapper = $this->getServiceLocator()->get('\\Accounting\\Model\\AccountMapper');
     if ($rows->count()) {
         foreach ($rows->toArray() as $row) {
             $transaction = new \Accounting\Model\Transaction();
             $transaction->exchangeArray($row);
             $accountingAccount = new \Accounting\Model\Account();
             $accountingAccount->setId($row['accountingAccountId']);
             $accountingAccountMapper->get($accountingAccount);
             /** tính toán commission */
             // lấy ra các sản phẩm trong hợp đồng
             $product = new \Crm\Model\Contract\Product();
             $product->setContractId($transaction->getItemId());
             $products = $productMapper->fetchAll($product);
             // lấy commission
             $commission = new \Crm\Model\Contract\Commission();
             $commission->setContractId($transaction->getItemId());
             $commissions = $commissionMapper->fetchAll($commission);
             $paymentAmounts = \Crm\Model\Contract\Payment::breakToCommission($transaction->getAmount(), $products, $commissions);
             /** Xóa các payment có transactionId=transaction.id */
             $delete = $dbSql->delete(\Crm\Model\Contract\PaymentMapper::TABLE_NAME);
             $delete->where(['transactionId' => $transaction->getId()]);
             $dbAdapter->query($dbSql->buildSqlString($delete), Adapter::QUERY_MODE_EXECUTE);
             /** Tạo mới payment */
             echo '<b>Tạo payment từ transaction ' . $transaction->getId() . '</b><br/>';
             foreach ($paymentAmounts as $employeeId => $amount) {
                 // lấy ra user của employee
                 $employee = new \Hrm\Model\Employee();
                 $employee->setId($employeeId);
                 $employeeMapper->get($employee);
                 if ($employee->getUserId()) {
                     $select = $dbSql->select(['p' => \Crm\Model\Contract\PaymentMapper::TABLE_NAME]);
                     $select->where(['transactionId' => $transaction->getId()]);
                     $select->where(['salemanId' => $employee->getUserId()]);
                     $select->limit(1);
                     $rowP = $dbAdapter->query($dbSql->buildSqlString($select), Adapter::QUERY_MODE_EXECUTE);
                     if ($rowP->count()) {
                         $rowP = (array) $rowP->current();
                         $payment = new \Crm\Model\Contract\Payment();
                         $payment->exchangeArray($rowP);
                         $payment->setAmount($amount);
                         $paymentMapper->save($payment);
                         echo '<p style="">Update payment ' . $payment->getId() . ' - amount: ' . $rowP['amount'] . ' -> ' . $payment->getAmount() . '</p><br/>';
                     } else {
                         $payment = new \Crm\Model\Contract\Payment();
                         $payment->setAmount($amount);
                         $payment->setSalemanId($employee->getUserId());
                         $payment->setAccountingAccountId($accountingAccount->getId());
                         $payment->setTransactionId($transaction->getId());
                         $payment->setDescription($transaction->getDescription());
                         $payment->setCompanyId($employee->getCompanyId());
                         $payment->setDepartmentId($employee->getDepartmentId());
                         $payment->setContractId($transaction->getItemId());
                         if ($accountingAccount->getType() == \Accounting\Model\Account::TYPE_CASH) {
                             $payment->setType(\Crm\Model\Contract\Payment::TYPE_CASH);
                         } else {
                             $payment->setType(\Crm\Model\Contract\Payment::TYPE_MONEY_TRANSFER);
                         }
                         if (in_array($transaction->getStatus(), [\Accounting\Model\Transaction::STATUS_ACCOUNTING, \Accounting\Model\Transaction::STATUS_PAYMENT])) {
                             $payment->setStatus(\Crm\Model\Contract\Payment::STATUS_CHECKED);
                         } elseif (in_array($transaction->getStatus(), [\Accounting\Model\Transaction::STATUS_NEW, \Accounting\Model\Transaction::STATUS_APPROVED])) {
                             $payment->setStatus(\Crm\Model\Contract\Payment::STATUS_UNCHECKED);
                         } else {
                             $payment->setStatus(\Crm\Model\Contract\Payment::STATUS_DELETED);
                         }
                         $payment->setCheckedById($transaction->getAccountingById());
                         $payment->setCheckedDate($transaction->getApplyDate());
                         $payment->setCheckedDateTime($transaction->getAccountingDateTime());
                         $payment->setCreatedById($transaction->getAccountingById() ?: $transaction->getCreatedById());
                         $payment->setCreatedDateTime($transaction->getAccountingDateTime() ?: $transaction->getCreatedDate() . ' ' . $transaction->getCreatedTime());
                         $paymentMapper->save($payment);
                         echo '--<span style="color:red;">Tạo mới payment ' . $payment->getId() . '</span></br/>';
                         echo '--------User: ' . $employee->getFullName() . '<br/>';
                         echo '--------Amount: ' . $payment->getAmount() . '/ ' . $transaction->getAmount() . '<br/>';
                     }
                 }
             }
         }
     }
     die;
 }