hansel23 / prices
价格接口和实现
1.0.0
2022-01-05 08:35 UTC
Requires
- php: >=7.4
- moneyphp/money: ^3.3.1
Requires (Dev)
- ext-json: *
- roave/security-advisories: dev-latest
- tm/tooly-composer-script: ^1.4.1
README
PHP 类型表示价格,包括含税金额、净额、增值税额和增值税率。价格包含含税、净额和增值税额,以及增值税率。缺失的值将根据实例化方法自动计算。
需求
- PHP >=7.4
- moneyphp/money
实例化
您有含税和净额,以及增值税率
$net = new Money( 1672, 'EUR' ); $gross = new Money( 1990, 'EUR' ); $vatRate = new VatRate( 19 ); $price = new GrossBasedPrice( $net, $gross, $vatRate ); $price->getGrossAmount(); //new Money( 1990, 'EUR' ) $price->getNetAmount(); //new Money( 1672, 'EUR' ) $price->getVatAmount(); //new Money( 318, 'EUR' ) $price->getVatRate(); //new VatRate( 19 )
您有含税金额和增值税率
$gross = new Money( 1990, 'EUR' ); $vatRate = new VatRate( 19 ); $price = GrossBasedPrice::fromGrossAmount( $gross, $vatRate ); $price->getGrossAmount(); //new Money( 1990, 'EUR' ) $price->getNetAmount(); //new Money( 1672, 'EUR' ) $price->getVatAmount(); //new Money( 318, 'EUR' ) $price->getVatRate(); //new VatRate( 19 )
您有净额和增值税率
$net = new Money( 1672, 'EUR' ); $vatRate = new VatRate( 19 ); $price = GrossBasedPrice::fromNetAmount( $net, $vatRate ); $price->getGrossAmount(); //new Money( 1990, 'EUR' ) $price->getNetAmount(); //new Money( 1672, 'EUR' ) $price->getVatAmount(); //new Money( 318, 'EUR' ) $price->getVatRate(); //new VatRate( 19 )
您想通过另一个价格类型创建一个新的价格类型
$grossBasedPrice = GrossBasedPrice::fromGrossAmount( new Money( 1990, 'EUR' ), new VatRate(19) ); $netBasedPrice = NetBasedPrice::fromPrice( $price ); $netBasedPrice->getGrossAmount(); //new Money( 1990, 'EUR' ) $netBasedPrice->getNetAmount(); //new Money( 1672, 'EUR' ) $netBasedPrice->getVatAmount(); //new Money( 318, 'EUR' ) $netBasedPrice->getVatRate(); //new VatRate( 19 )
在某些情况下,价格是根据净额还是含税金额生成的可能很重要。
示例
- 增值税率:19 %
- 含税金额:9,99 EUR
- 计算后的净额:8,39 EUR (9,99 / 1,19 = 四舍五入 8,39)
- 净额:8,39 EUR
- 计算后的含税金额:9,98 EUR (8,39 * 1,19 = 四舍五入 9,98)
fromNetAndGrossAmount
方法,该方法独立计算增值税,不存在,因为计算不可靠。有些国家的增值税率有小数位数。如果考虑这些位数,四舍五入可能会导致错误的增值税率。
示例
- 含税:9,99 EUR
- 净额:8,39 EUR
- 期望的增值税率:19,00 %
- 计算后的增值税率,四舍五入到两位小数:19,07 %
增值税率
您可以通过浮点值或整数值实例化 VatRate
。整数值必须是浮点值乘以100。以下示例生成相同的增值税率。增值税率是 21,70 %。
$vatRateByFloat = new VatRate( 21.7 ); $vatRateByInt = VatRate::fromInt( 2170 ); $vatRateByFloat->equals( $vatRateByInt ); //true
价格的乘除运算
当乘以数量时,有两种计算增值税的方法。这是 GrossBasedPrice
和 NetBasePrice
的区别。
基于净额的价格
增值税是在将单价乘以数量之后计算的。
示例: 90,82 € * 10 = 908,20 € * 1.19 = 1080,76 €
$unitPrice = NetBasedPrice::fromGrossAmount( new Money( 10808, 'EUR' ) ); $totalPrice = $price->multiply( 10 ); $unitPrice->getGrossAmount(); //new Money( 10808, 'EUR' ) $unitPrice->getNetAmount(); //new Money( 9082, 'EUR' ) $totalPrice->getGrossAmount(); //new Money( 108076, 'EUR' ) $totalPrice->getNetAmount(); //new Money( 90820, 'EUR' )
基于含税的价格
首先,对单价计算增值税,然后乘以数量。
示例: 90,82 € * 1,19 = 108,08 € * 3 = 1080,80 €
$unitPrice = GrossBasedPrice::fromNetAmount( new Money( 9082, 'EUR' ) ); $totalPrice = $price->multiply( 10 ); $unitPrice->getGrossAmount(); //new Money( 10808, 'EUR' ) $unitPrice->getNetAmount(); //new Money( 9082, 'EUR' ) $totalPrice->getGrossAmount(); //new Money( 108080, 'EUR' ) $totalPrice->getNetAmount(); //new Money( 90824, 'EUR' )
除法与乘法类似,只是当然您是除法而不是乘法。
加法和减法
$price = GrossBasedPrice::fromGrossAmount( new Money( 1000, 'EUR' ) ); $sum = $price->add( GrossBasedPrice::fromGrossAmount( new Money( 1000, 'EUR' ) ) ); $sum->getGrossAmount(); //new Money( 2000, 'EUR' ) $difference = $price->subtract( GrossBasedPrice::fromGrossAmount( new Money( 1000, 'EUR' ) ) ); $difference->getGrossAmount(); //new Money( 0, 'EUR' )
总价
虽然 RepresentsPrice
(或其实现)主要用于订单项的价格,但 RepresentsTotalPrice
(或其实现)用作订单的总价。
在这种情况下,价格不仅仅是相加,还可以按增值税率分组返回,例如。
$prices = [ GrossBasedPrice::fromGrossAmount( new Money( 100, 'EUR' ), new VatRate( 19 ) ), FakePriceImplementation::fromGrossAmount( new Money( 300, 'EUR' ), new VatRate( 7 ) ), ]; $additionalPrice = GrossBasedPrice::fromGrossAmount( new Money( 100, 'EUR' ), new VatRate( 16.5 ) ); $totalPrice = new TotalPrice( 'EUR', $prices ); $totalPrice->addPrice( $additionalPrice ); $anotherTotalPrice = new TotalPrice( 'EUR', [ NetBasedPrice::fromGrossAmount( new Money( 200, 'EUR' ), new VatRate( 16.5 ) ), FakePriceImplementation::fromGrossAmount( new Money( 300, 'EUR' ), new VatRate( 16.5 ) ), ] ); $totalPrice->addTotalPrice( $anotherTotalPrice ); $totalPrice->getPrices(); // Array with prices from $prices, $additionalPrice and the prices from $anotherTotalPrice $totalPrice->getTotalGrossAmount(); // new Money( 1000, 'EUR' ) (100 + 300 + 100 + 200 + 300) $totalPrice->getTotalNetAmount(); // new Money( 794, 'EUR' ) (100/1,19 + 300/1,07 + (200 + 300)/1,165) $totalPrice->getTotalVatAmount(); // new Money( 206, 'EUR ) (1000 - 794)
按增值税率分组返回。
$prices = [ GrossBasedPrice::fromGrossAmount( new Money( 100, 'EUR' ), new VatRate( 19 ) ), GrossBasedPrice::fromGrossAmount( new Money( 200, 'EUR' ), new VatRate( 19 ) ), FakePriceImplementation::fromGrossAmount( new Money( 300, 'EUR' ), new VatRate( 7 ) ), ]; $totalPrice = new TotalPrice( 'EUR', $prices ); $totalPrice->getPricesGroupedByVatRates(); /** [ 1900 => [ GrossBasedPrice::fromGrossAmount( new Money( 100, 'EUR' ), new VatRate( 19 ) ), GrossBasedPrice::fromGrossAmount( new Money( 200, 'EUR' ), new VatRate( 19 ) ), ], 700 => [ FakePriceImplementation::fromGrossAmount( new Money( 300, 'EUR' ), new VatRate( 7 ) ) ] ] **/
Json
$prices = [ GrossBasedPrice::fromGrossAmount( new Money( 100, 'EUR' ), new VatRate( 19 ) ), FakePriceImplementation::fromGrossAmount( new Money( 300, 'EUR' ), new VatRate( 19 ) ), NetBasedPrice::fromGrossAmount( new Money( 200, 'EUR' ), new VatRate( 7 ) ), ]; $totalPrice = new TotalPrice( 'EUR', $prices ); json_encode( $totalPrice, JSON_PRETTY_PRINT ); /** { "1900": [{ "gross": { "amount": "100", "currency": "EUR" }, "net": { "amount": "84", "currency": "EUR" }, "vat": { "amount": "16", "currency": "EUR" } }, { "gross": { "amount": "300", "currency": "EUR" }, "net": { "amount": "252", "currency": "EUR" }, "vat": { "amount": "48", "currency": "EUR" } }], "700": [{ "gross": { "amount": "200", "currency": "EUR" }, "net": { "amount": "187", "currency": "EUR" }, "vat": { "amount": "13", "currency": "EUR" } }] } **/