/** * Retrieve tax record * @return array|bool */ private function getTaxRecords() { $taxMdl = new TaxItemsModel(); if (($taxes = $taxMdl->get()) === false) { return false; } $result = []; foreach ($taxes as $tax) { $result[$tax['id']] = $tax; } return $result; }
/** * Email the sale receipt to the specified address * @param $email * @return mixed */ private function emailReceipt($email) { // get config $config = new WposAdminSettings(); $recval = $config->getSettingsObject("pos"); $genval = $config->getSettingsObject("general"); $utils = new WposAdminUtilities(); $utils->setCurrencyFormat($genval->currencyformat); // create receipt $html = '<div style="padding: 10px; padding-left: 5px; padding-right: 5px; margin-top:5px; width:300px; margin: auto; background-color:#FFFFFF;"><img width="95%" src="http://' . $_SERVER['SERVER_ADDR'] . $recval->recemaillogo . '"/><br/>'; $html .= '<h3 style="text-align: center; margin: 5px;">' . $genval->bizname . '</h3>'; $html .= '<p style="text-align: center"><strong>' . $recval->recline2 . '</strong>'; if ($recval->recline3 != "") { $html .= '<br/><strong style="text-align: center">' . $recval->recline3 . '</strong>'; } $html .= '</p>'; // body $html .= '<p style="padding-top: 5px;">Transaction Ref: ' . $this->ref . '<br/>'; $html .= 'Sale Time: ' . WposAdminUtilities::getDateFromTimeStamp($this->jsonobj->processdt, $genval->dateformat) . '</p>'; // items $html .= '<table style="width: 100%; margin-bottom: 4px; font-size: 13px;">'; foreach ($this->jsonobj->items as $item) { // item mod details $modStr = ""; if (isset($item->mod)) { foreach ($item->mod->items as $mod) { $modStr .= '<br/> ' . (isset($mod->qty) ? ($mod->qty > 0 ? '+ ' : '') . $mod->qty . ' ' : '') . $mod->name . (isset($mod->value) ? ': ' . $mod->value : '') . ' (' . $utils->currencyFormat($mod->price) . ')'; } } $html .= '<tr><td>' . $item->qty . "x " . $item->name . " (" . $utils->currencyFormat($item->unit) . ")" . $modStr . '</td><td style="text-align: right;">' . $utils->currencyFormat($item->price) . '</td></tr>'; } $html .= '<tr style="height: 5px;"><td></td><td></td></tr>'; // totals // subtotal $taxcount = count(get_object_vars($this->jsonobj->taxdata)); if ($taxcount > 0 || $this->jsonobj->discount > 0) { // only add if discount or taxes $html .= '<tr><td><b>Subtotal: </b></td><td style="text-align: right;"><b style="text-decoration: overline;">' . $utils->currencyFormat($this->jsonobj->subtotal) . '</b></td></tr>'; } // taxes if ($taxcount) { $taxMdl = new TaxItemsModel(); $taxes = $taxMdl->get(); foreach ($taxes as $tax) { $taxes[$tax['id']] = $tax; } foreach ($this->jsonobj->taxdata as $key => $tax) { $taxstr = $taxes[$key]; $taxstr = $taxstr['name'] . ' (' . $taxstr['value'] . '%)'; $html .= '<tr><td>' . $taxstr . ':</td><td style="text-align: right;">' . $utils->currencyFormat($tax) . '</td></tr>'; } } // discount $html .= $this->jsonobj->discount > 0 ? '<tr><td>' . $this->jsonobj->discount . '% Discount</td><td style="text-align: right;">' . $utils->currencyFormat(abs(floatval($this->jsonobj->total) - (floatval($this->jsonobj->subtotal) + floatval($this->jsonobj->tax)))) . '</td></tr>' : ''; // grand total $html .= '<tr><td><b>Total (' . $this->jsonobj->numitems . ' items): </b></td><td style="text-align: right;"><b style="text-decoration: overline;">' . $utils->currencyFormat($this->jsonobj->total) . '</b></td></tr>'; $html .= '<tr style="height: 2px;"><td></td><td></td></tr>'; // payments foreach ($this->jsonobj->payments as $payment) { $html .= '<tr><td><span style="font-size: 14px;">' . ucfirst($payment->method) . '</p></td><td style="text-align: right;"><p style="font-size: 14px;">' . $utils->currencyFormat($payment->amount) . '</span></td></tr>'; if ($payment->method == 'cash') { // If cash print tender & change $html .= '<tr><td>Tendered:</td><td style="text-align: right;">' . $utils->currencyFormat($payment->tender) . '</td></tr>'; $html .= '<tr><td>Change:</td><td style="text-align: right;">' . $utils->currencyFormat($payment->change) . '</td></tr>'; } } $html .= '</table>'; // refunds if (isset($this->jsonobj->refunddata)) { $html .= '<p style="margin-top: 0; margin-bottom: 5px; font-size: 13px;"><strong>Refund</strong></p><table style="width: 100%; font-size: 13px;">'; foreach ($this->jsonobj->refundata as $refund) { $html .= '<tr><td>' . WposAdminUtilities::getDateFromTimeStamp($refund->processdt, $genval->dateformat) . ' (' . sizeof($refund->items) . ' items)</td><td>' . ucfirst($refund->method) . '<span style="float: right;">' . $refund->amount . '</span></td></tr>'; } $html .= '</table>'; } // void if (isset($this->jsonobj->voiddata)) { $html .= '<h2 style="text-align: center; color: #dc322f; margin-top: 5px;">VOID SALE</h2>'; } // footer $html .= '<p style="text-align: center;"><strong>' . $recval->recfooter . '</strong><br/>'; if ($recval->recqrcode != "") { $html .= '<img style="text-align: center;" height="99" src="http://' . $_SERVER['SERVER_ADDR'] . '/wpos/asset/images/qrcode.png"/>'; } $html .= '</p></div>'; $template = '<html><head><link media="all" href="https://' . $_SERVER['SERVER_NAME'] . '/wpos/admin/assets/css/bootstrap.min.css" rel="stylesheet"/><link media="all" rel="stylesheet" href="https://' . $_SERVER['SERVER_NAME'] . '/wpos/admin/assets/css/font-awesome.min.css"/><link media="all" rel="stylesheet" href="https://' . $_SERVER['SERVER_NAME'] . '/wpos/admin/assets/css/ace-fonts.css"/><link media="all" rel="stylesheet" href="https://' . $_SERVER['SERVER_ADDR'] . '/wpos/admin/assets/css/ace.min.css"/></head><body>%message%</body>'; $html = str_replace("%message%", $html, $template); $wposMail = new WposMail($genval); if (($mresult = $wposMail->sendHtmlEmail($email, 'Your ' . $genval->bizname . ' receipt', $html)) !== true) { return 'Failed to email receipt: ' . $mresult; } else { return true; } }
/** * Delete a tax rule * @param $result * @return mixed */ public function deleteTaxItem($result) { // validate input if (!is_numeric($this->data->id)) { $result['error'] = "A valid id must be supplied"; return $result; } $taxItemMdl = new TaxItemsModel(); $qresult = $taxItemMdl->remove($this->data->id); if ($qresult === false) { $result['error'] = "Could not delete the tax item: " . $taxItemMdl->errorInfo; } else { $result['data'] = true; $this->broadcastTaxUpdate(); // log data Logger::write("Tax item deleted with id:" . $this->data->id, "TAX"); } return $result; }
/** * Generate invoice html * @return string */ private function generateInvoiceHtml() { // copy invoice data, set tax values /** @noinspection PhpUnusedLocalVariableInspection */ $invoice = $this->trans; $taxMdl = new TaxItemsModel(); $taxdata = $taxMdl->get(); $taxes = []; foreach ($taxdata as $value) { $taxes[$value['id']] = (object) $value; } // Get general settings $config = new WposAdminSettings(); $settings = $config->getSettingsObject("general"); $settings->payinst = $config->getSettingsObject("invoice")->payinst; // Get customer record $custMdl = new CustomerModel(); /** @noinspection PhpUnusedLocalVariableInspection */ $customer = (object) $custMdl->get($this->trans->custid)[0]; $utils = new WposAdminUtilities(); $utils->setCurrencyFormat($settings->currencyformat); // start output buffer and capture template output ob_start(); include $_SERVER['DOCUMENT_ROOT'] . "/docs/templates/invoice.php"; $html = ob_get_contents(); ob_end_clean(); return $html; }
/** * @param array $result * * @return array Returns an array of tax objects */ public static function getTaxes($result = []) { $taxItemsMdl = new TaxItemsModel(); $taxItemsArr = $taxItemsMdl->get(); if (is_array($taxItemsArr)) { $taxItems = []; foreach ($taxItemsArr as $taxItem) { $taxItems[$taxItem['id']] = $taxItem; } $result['data'] = []; $result['data']['items'] = $taxItems; $taxRulesMdl = new TaxRulesModel(); $taxRulesArr = $taxRulesMdl->get(); if (is_array($taxRulesArr)) { $taxRules = []; foreach ($taxRulesArr as $taxRule) { $ruleData = json_decode($taxRule['data']); $ruleData->id = $taxRule['id']; $taxRules[$taxRule['id']] = $ruleData; } $result['data']['rules'] = $taxRules; } else { $result['error'] = "Tax data could not be retrieved: " . $taxRulesMdl->errorInfo; } } else { $result['error'] = "Tax data could not be retrieved: " . $taxItemsMdl->errorInfo; } return $result; }
/** * Get tax statistics from the current range * @param $result * @return mixed */ public function getTaxStats($result) { $stats = []; $itemsMdl = new SaleItemsModel(); // check if params set, if not set defaults $stime = isset($this->data->stime) ? $this->data->stime : strtotime('-1 week') * 1000; $etime = isset($this->data->etime) ? $this->data->etime : time() * 1000; if (is_array($taxtotals = $itemsMdl->getTaxTotals($stime, $etime, true, $this->data->type))) { foreach ($taxtotals as $tax) { $stats[$tax['taxid']] = new stdClass(); $stats[$tax['taxid']]->refs = $tax['refs']; $stats[$tax['taxid']]->name = $tax['taxname']; $stats[$tax['taxid']]->qtyitems = $tax['qtyitems']; //$stats[$tax['taxid']]->salebalance = number_format($tax['saletotal']-$tax['refundtotal'], 2); $stats[$tax['taxid']]->saletotal = number_format($tax['saletotal'], 2); $stats[$tax['taxid']]->refundtotal = number_format($tax['refundtotal'], 2); if ($tax['taxid'] == 1) { $stats[$tax['taxid']]->saletax = number_format(0.0, 2); $stats[$tax['taxid']]->refundtax = number_format(0.0, 2); } else { $taxMdl = new TaxItemsModel(); $taxdata = $taxMdl->get($tax['taxid']); if ($taxdata === false) { $result['error'] = "Could not calculate tax"; return $result; } $taxdiv = $taxdata[0]['divisor']; $stats[$tax['taxid']]->saletax = round($tax['saletotal'] / $taxdiv, 2); $stats[$tax['taxid']]->refundtax = round($tax['refundtotal'] / $taxdiv, 2); } $stats[$tax['taxid']]->balance = number_format($stats[$tax['taxid']]->saletax - $stats[$tax['taxid']]->refundtax, 2); $stats[$tax['taxid']]->saletax = number_format($stats[$tax['taxid']]->saletax, 2); $stats[$tax['taxid']]->refundtax = number_format($stats[$tax['taxid']]->refundtax, 2); } // Get cash rounding total $roundtotals = $itemsMdl->getRoundingTotal($stime, $etime); if ($roundtotals !== false) { $stats[0] = new stdClass(); $stats[0]->refs = $roundtotals[0]['refs']; $stats[0]->name = "Cash Rounding"; $stats[0]->qty = $roundtotals[0]['num']; $stats[0]->total = $roundtotals[0]['total']; } else { $result['error'] = $itemsMdl->errorInfo; } } else { $result['error'] = $itemsMdl->errorInfo; } $result['data'] = $stats; return $result; }
/** * @param array $result * * @return array Returns an array of tax objects */ public function getTaxes($result) { $taxItemsMdl = new TaxItemsModel(); $taxItems = $taxItemsMdl->get(); if (is_array($taxItems)) { $taxes = []; foreach ($taxItems as $taxItem) { $taxes[$taxItem['id']] = $taxItem; } $result['data'] = $taxes; } else { $result['error'] = $taxItemsMdl->errorInfo; } return $result; }
/** * Get general config used by customer dashboard * @param $result * @return mixed */ public function getSettings($result) { $settings = WposAdminSettings::getSettingsObject('general'); unset($settings->gcontacttoken); $taxMdl = new TaxItemsModel(); $taxes = $taxMdl->get(); $taxobj = []; foreach ($taxes as $tax) { $taxobj[$tax['id']] = $tax; } $setobj = ["general" => $settings, "tax" => $taxobj]; $result['data'] = $setobj; return $result; }
/** * Get tax statistics from the current range * @param $result * @return mixed */ public function getTaxStats($result) { $stats = []; $itemsMdl = new SaleItemsModel(); // check if params set, if not set defaults $stime = isset($this->data->stime) ? $this->data->stime : strtotime('-1 week') * 1000; $etime = isset($this->data->etime) ? $this->data->etime : time() * 1000; if (is_array($saleitems = $itemsMdl->getTotalsRange($stime, $etime, true, $this->data->type))) { $taxMdl = new TaxItemsModel(); $taxdata = $taxMdl->get(); $taxes = []; foreach ($taxdata as $value) { $taxes[$value['id']] = (object) $value; } foreach ($saleitems as $saleitem) { $itemtax = json_decode($saleitem['tax']); if ($itemtax->total == 0) { if (!array_key_exists(-1, $stats)) { $stats[-1] = new stdClass(); $stats[-1]->refs = []; $stats[-1]->name = "Untaxed"; $stats[-1]->qtyitems = 0; $stats[-1]->saletotal = 0; $stats[-1]->refundtotal = 0; $stats[-1]->saletax = 0; $stats[-1]->refundtax = 0; } if (!in_array($saleitem['ref'], $stats[-1]->refs)) { $stats[-1]->refs[] = $saleitem['ref']; } $stats[-1]->qtyitems += $saleitem['qty']; $stats[-1]->saletotal += $saleitem['itemtotal']; $stats[-1]->refundtotal += $saleitem['refundtotal']; } else { // subtotal excludes tax, factors in discount $discountedtax = $saleitem['discount'] > 0 ? round($itemtax->total - $itemtax->total * ($saleitem['discount'] / 100), 2) : $itemtax->total; //echo($discountedtax); $itemsubtotal = $saleitem['itemtotal'] - $discountedtax; $refundsubtotal = $saleitem['refundtotal'] - round($discountedtax / $saleitem['qty'] * $saleitem['refundqty'], 2); foreach ($itemtax->values as $key => $value) { if (!array_key_exists($key, $stats)) { $stats[$key] = new stdClass(); $stats[$key]->refs = []; $stats[$key]->name = isset($taxes[$key]) ? $taxes[$key]->name : "Unknown"; $stats[$key]->qtyitems = 0; $stats[$key]->saletotal = 0; $stats[$key]->refundtotal = 0; //$stats[$key]->saletax = 0; //$stats[$key]->refundtax = 0; } if (!in_array($saleitem['ref'], $stats[$key]->refs)) { $stats[$key]->refs[] = $saleitem['ref']; } $stats[$key]->qtyitems += $saleitem['qty']; $stats[$key]->saletotal += $itemsubtotal; // subtotal excludes tax, factors in discount $stats[$key]->refundtotal += $refundsubtotal; //$stats[$key]->saletax += $saleitem['discount']>0 ? round($value - ($value*($saleitem['discount']/100)), 2) : $value; // $stats[$key]->refundtax += $saleitem['discount']>0 ? (round($value/($saleitem['discount']/100), 2)/$saleitem['qty'])*$saleitem['refundqty']: ($value/$saleitem['qty'])*$saleitem['refundqty']; } } } foreach ($stats as $key => $value) { $taxitems = WposAdminUtilities::getTaxTable()['items']; $stats[$key]->saletax = round($taxitems[$key]['multiplier'] * $stats[$key]->saletotal, 2); $stats[$key]->refundtax = round($taxitems[$key]['multiplier'] * $stats[$key]->refundtotal, 2); $stats[$key]->balance = number_format($stats[$key]->saletax - $stats[$key]->refundtax, 2); } // Get cash rounding total $roundtotals = $itemsMdl->getRoundingTotal($stime, $etime); if ($roundtotals !== false) { $stats[0] = new stdClass(); $stats[0]->refs = $roundtotals[0]['refs']; $stats[0]->name = "Cash Rounding"; $stats[0]->qty = $roundtotals[0]['num']; $stats[0]->total = $roundtotals[0]['total']; } else { $result['error'] = $itemsMdl->errorInfo; } } else { $result['error'] = $itemsMdl->errorInfo; } $result['data'] = $stats; return $result; }