hansel23/prices

价格接口和实现

1.0.0 2022-01-05 08:35 UTC

This package is auto-updated.

Last update: 2024-08-28 03:33:52 UTC


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

价格的乘除运算

当乘以数量时,有两种计算增值税的方法。这是 GrossBasedPriceNetBasePrice 的区别。

基于净额的价格

增值税是在将单价乘以数量之后计算的。

示例: 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"
		}
	}]
}
**/