You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求修改WHMCS Sales Tax Liability报告:添加自定义字段及税率

解决方案:WHMCS销售税负债报告添加VAT编号与税率显示

一、添加客户VAT编号(customfield14)

客户自定义字段存储在tblcustomfieldsvalues表中,需关联该表获取customfield14的值,具体修改如下:

  1. 关联自定义字段表并查询值
    在获取发票数据的查询中,新增leftJoin关联tblcustomfieldsvalues,并选中对应字段:
$results = Capsule::table('tblinvoices')
    ->select(
        'tblinvoices.*',
        'tblclients.firstname',
        'tblclients.lastname',
        'tblclients.companyname',
        'cfv14.value as vat_number' // 新增:获取customfield14的值
    )
    ->distinct()
    ->join('tblclients', 'tblclients.id', '=', 'tblinvoices.userid')
    // 新增:关联自定义字段表,筛选fieldid=14的记录
    ->leftJoin('tblcustomfieldsvalues as cfv14', function($join) {
        $join->on('cfv14.relid', '=', 'tblclients.id')
             ->where('cfv14.fieldid', '=', 14);
    })
    ->leftJoin('tblinvoiceitems', function ($join) {
        $join->on('tblinvoiceitems.invoiceid', '=', 'tblinvoices.id');
        $join->on(function ($join) {
            $join
                ->on('tblinvoiceitems.type', '=', Capsule::raw('"Add Funds"'))
                ->orOn('tblinvoiceitems.type', '=', Capsule::raw('"Invoice"'));
        });
    })
    ->whereBetween('tblinvoices.datepaid', [$queryStartDate, $queryEndDate])
    ->where('tblinvoices.status', '=', 'Paid')
    ->where('tblclients.currency', '=', $currencyID)
    ->whereNull('tblinvoiceitems.id')
    ->orderBy('date', 'asc')
    ->get()
    ->all();
  1. 修改表头添加VAT列
    在表头数组中新增VAT编号列:
$reportdata["tableheadings"] = array(
    $aInt->lang('fields', 'invoiceid'),
    $aInt->lang('fields', 'clientname'),
    'VAT编号', // 新增列
    $aInt->lang('fields', 'invoicenum'),
    $aInt->lang('fields', 'invoicedate'),
    $aInt->lang('fields', 'datepaid'),
    $aInt->lang('fields', 'subtotal'),
    $aInt->lang('fields', 'tax'),
    '税率1(%)', // 预留税率列
    '税率2(%)',
    $aInt->lang('fields', 'credit'),
    $aInt->lang('fields', 'total'),
);
  1. 在循环中显示VAT编号
    处理空值避免显示空白,将值加入表格行:
foreach ($results as $result) {
    // ... 原有变量定义
    $vat_number = !empty($result->vat_number) ? $result->vat_number : '-'; // 处理空值
    
    $reportdata["tablevalues"][] = [
        "{$id}",
        "{$client}",
        $vat_number, // 新增VAT编号
        "{$invoicenum}",
        "{$date}",
        "{$datepaid}",
        format_as_currency($subtotal),
        format_as_currency($tax),
        // 后续税率值将在此处添加
        format_as_currency($credit),
        format_as_currency($total),
    ];
}

二、显示税率

WHMCS发票表tblinvoices的taxrate和taxrate2字段存储了对应税种的百分比税率,只需在查询中读取并添加到表格即可:

  1. 读取税率字段
    由于tblinvoices.*已包含taxrate和taxrate2,无需修改查询的select部分,直接在循环中取值:
foreach ($results as $result) {
    // ... 原有变量定义
    $tax_rate1 = !empty($result->taxrate) ? $result->taxrate . '%' : '-';
    $tax_rate2 = !empty($result->taxrate2) ? $result->taxrate2 . '%' : '-';
    
    $reportdata["tablevalues"][] = [
        "{$id}",
        "{$client}",
        $vat_number,
        "{$invoicenum}",
        "{$date}",
        "{$datepaid}",
        format_as_currency($subtotal),
        format_as_currency($tax),
        $tax_rate1, // 新增税率1
        $tax_rate2, // 新增税率2
        format_as_currency($credit),
        format_as_currency($total),
    ];
}

修改后的完整代码

<?php

use WHMCS\Carbon;
use WHMCS\Database\Capsule;

if (!defined("WHMCS")) {
    die("This file cannot be accessed directly");
}

$reportdata["title"] = "Sales Tax Liability";
$reportdata["description"] = "This report shows sales tax liability for the selected period";

$reportdata["currencyselections"] = true;

$range = App::getFromRequest('range');
if (!$range) {
    $today = Carbon::today()->endOfDay();
    $lastWeek = Carbon::today()->subDays(6)->startOfDay();
    $range = $lastWeek->toAdminDateFormat() . ' - ' . $today->toAdminDateFormat();
}
$currencyID = (int) $currencyid;

$reportdata['headertext'] = '';
if (!$print) {
    $reportdata['headertext'] = <<<HTML
<form method="post" action="reports.php?report={$report}&currencyid={$currencyid}&calculate=true">
    <div class="report-filters-wrapper">
        <div class="inner-container">
            <h3>Filters</h3>
            <div class="row">
                <div class="col-md-3 col-sm-6">
                    <div class="form-group">
                        <label for="inputFilterDate">{$dateRangeText}</label>
                        <div class="form-group date-picker-prepend-icon">
                            <label for="inputFilterDate" class="field-icon">
                                <i class="fal fa-calendar-alt"></i>
                            </label>
                            <input id="inputFilterDate"
                                   type="text"
                                   name="range"
                                   value="{$range}"
                                   class="form-control date-picker-search"
                            />
                        </div>
                    </div>
                </div>
            </div>
            <button type="submit" class="btn btn-primary">
                {$aInt->lang('reports', 'generateReport')}
            </button>
        </div>
    </div>
</form>
HTML;
}

if ($calculate) {
    $dateRange = Carbon::parseDateRangeValue($range);
    $queryStartDate = $dateRange['from']->toDateTimeString();
    $queryEndDate = $dateRange['to']->toDateTimeString();

    $result = Capsule::table('tblinvoices')
        ->select(
            Capsule::raw('count(*) as `count`'),
            Capsule::raw('sum(total) as `total`'),
            Capsule::raw('sum(tblinvoices.credit) as `credit`'),
            Capsule::raw('sum(tax) as `tax`'),
            Capsule::raw('sum(tax2) as `tax2`')
        )
        ->distinct()
        ->join('tblclients', 'tblclients.id', '=', 'tblinvoices.userid')
        ->leftJoin('tblinvoiceitems', function ($join) {
            $join->on('tblinvoiceitems.invoiceid', '=', 'tblinvoices.id');
            $join->on(function ($join) {
                $join
                    ->on('tblinvoiceitems.type', '=', Capsule::raw('"Add Funds"'))
                    ->orOn('tblinvoiceitems.type', '=', Capsule::raw('"Invoice"'));
            });
        })
        ->whereBetween('tblinvoices.datepaid', [$queryStartDate, $queryEndDate])
        ->where('tblinvoices.status', '=', 'Paid')
        ->where('tblclients.currency', '=', $currencyID)
        ->whereNull('tblinvoiceitems.id')
        ->first();

    $numinvoices = $result->count;
    $total = ($result->total + $result->credit);
    $tax = $result->tax;
    $tax2 = $result->tax2;

    if (!$total) $total="0.00";
    if (!$tax) $tax="0.00";
    if (!$tax2) $tax2="0.00";

    $reportdata["headertext"] .= "<br>$numinvoices Invoices Found<br><B>Total Invoiced:</B> ".formatCurrency($total)." &nbsp; <B>Tax Level 1 Liability:</B> ".formatCurrency($tax)." &nbsp; <B>Tax Level 2 Liability:</B> ".formatCurrency($tax2);
}

$reportdata["headertext"] .= "</center>";

$reportdata["tableheadings"] = array(
    $aInt->lang('fields', 'invoiceid'),
    $aInt->lang('fields', 'clientname'),
    'VAT编号',
    $aInt->lang('fields', 'invoicenum'),
    $aInt->lang('fields', 'invoicedate'),
    $aInt->lang('fields', 'datepaid'),
    $aInt->lang('fields', 'subtotal'),
    $aInt->lang('fields', 'tax'),
    '税率1(%)',
    '税率2(%)',
    $aInt->lang('fields', 'credit'),
    $aInt->lang('fields', 'total'),
);

$results = Capsule::table('tblinvoices')
    ->select(
        'tblinvoices.*',
        'tblclients.firstname',
        'tblclients.lastname',
        'tblclients.companyname',
        'cfv14.value as vat_number'
    )
    ->distinct()
    ->join('tblclients', 'tblclients.id', '=', 'tblinvoices.userid')
    ->leftJoin('tblcustomfieldsvalues as cfv14', function($join) {
        $join->on('cfv14.relid', '=', 'tblclients.id')
             ->where('cfv14.fieldid', '=', 14);
    })
    ->leftJoin('tblinvoiceitems', function ($join) {
        $join->on('tblinvoiceitems.invoiceid', '=', 'tblinvoices.id');
        $join->on(function ($join) {
            $join
                ->on('tblinvoiceitems.type', '=', Capsule::raw('"Add Funds"'))
                ->orOn('tblinvoiceitems.type', '=', Capsule::raw('"Invoice"'));
        });
    })
    ->whereBetween('tblinvoices.datepaid', [$queryStartDate, $queryEndDate])
    ->where('tblinvoices.status', '=', 'Paid')
    ->where('tblclients.currency', '=', $currencyID)
    ->whereNull('tblinvoiceitems.id')
    ->orderBy('date', 'asc')
    ->get()
    ->all();

foreach ($results as $result) {
    $id = $result->id;
    $userid = $result->userid;
    $client = "{$result->firstname} {$result->lastname} - {$result->companyname}";
    $vat_number = !empty($result->vat_number) ? $result->vat_number : '-';
    $invoicenum = "{$result->invoicenum}";
    $date = fromMySQLDate($result->date);
    $datepaid = fromMySQLDate($result->datepaid);
    $currency = getCurrency($userid);
    $subtotal = $result->subtotal;
    $credit = $result->credit;
    $tax = ($result->tax + $result->tax2);
    $total = ($result->total + $credit);
    $tax_rate1 = !empty($result->taxrate) ? $result->taxrate . '%' : '-';
    $tax_rate2 = !empty($result->taxrate2) ? $result->taxrate2 . '%' : '-';

    $reportdata["tablevalues"][] = [
        "{$id}",
        "{$client}",
        $vat_number,
        "{$invoicenum}",
        "{$date}",
        "{$datepaid}",
        format_as_currency($subtotal),
        format_as_currency($tax),
        $tax_rate1,
        $tax_rate2,
        format_as_currency($credit),
        format_as_currency($total),
    ];
}

$data["footertext"]="This report excludes invoices that affect a clients credit balance "
    . "since this income will be counted and reported when it is applied to invoices for products/services.";
?>

注意事项

  • 确认customfield14是客户自定义字段的实际ID,可在WHMCS后台自定义字段管理中查看对应字段ID。
  • 若税率字段为空(无对应税种),代码中已处理为显示-,可根据需求调整显示内容。

内容的提问来源于stack exchange,提问作者Acidburns

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:37:04