-
Notifications
You must be signed in to change notification settings - Fork 2
Feat: invoice basic implementation #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c80894c
5b80942
c7c58a8
e9c98b0
1c22baa
1395e1a
8c44863
cf31f2a
0bcf042
4b8fde6
933a3b8
1f39400
fd5e73e
835a19a
5b1deed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<?php | ||
|
||
namespace Utopia\Pay\Credit; | ||
|
||
class Credit | ||
{ | ||
public const STATUS_ACTIVE = 'active'; | ||
|
||
public const STATUS_APPLIED = 'applied'; | ||
|
||
public const STATUS_EXPIRED = 'expired'; | ||
|
||
/** | ||
* @param string $id | ||
* @param float $credits | ||
* @param int $creditsUsed | ||
* @param string $status | ||
*/ | ||
public function __construct(private string $id, private float $credits, private float $creditsUsed = 0, private string $status = self::STATUS_ACTIVE) | ||
{ | ||
} | ||
|
||
public function getStatus(): string | ||
{ | ||
return $this->status; | ||
} | ||
|
||
public function markAsApplied(): static | ||
{ | ||
$this->status = self::STATUS_APPLIED; | ||
|
||
return $this; | ||
} | ||
|
||
public function getId(): string | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function setId(string $id): static | ||
{ | ||
$this->id = $id; | ||
|
||
return $this; | ||
} | ||
|
||
public function getCredits(): float | ||
{ | ||
return $this->credits; | ||
} | ||
|
||
public function setCredits(float $credits): static | ||
{ | ||
$this->credits = $credits; | ||
|
||
return $this; | ||
} | ||
|
||
public function getCreditsUsed(): float | ||
{ | ||
return $this->creditsUsed; | ||
} | ||
|
||
public function setCreditsUsed(float $creditsUsed): static | ||
{ | ||
$this->creditsUsed = $creditsUsed; | ||
|
||
return $this; | ||
} | ||
|
||
public function hasAvailableCredits(): bool | ||
{ | ||
return $this->credits > 0; | ||
} | ||
|
||
public function useCredits(float $amount): float | ||
{ | ||
if ($amount <= 0) { | ||
return 0; | ||
} | ||
|
||
$creditsToUse = min($amount, $this->credits); | ||
$this->credits -= $creditsToUse; | ||
$this->creditsUsed += $creditsToUse; | ||
|
||
if ($this->credits === 0) { | ||
$this->status = self::STATUS_APPLIED; | ||
} | ||
|
||
return $creditsToUse; | ||
} | ||
|
||
public function setStatus($status): static | ||
{ | ||
$this->status = $status; | ||
|
||
return $this; | ||
} | ||
|
||
public function isFullyUsed(): bool | ||
{ | ||
return $this->credits === 0 || $this->status === self::STATUS_APPLIED; | ||
} | ||
|
||
public static function fromArray(array $data): self | ||
{ | ||
return new self($data['id'] ?? $data['$id'] ?? '', | ||
$data['credits'] ?? 0.0, | ||
$data['creditsUsed'] ?? 0.0, | ||
$data['status'] ?? self::STATUS_ACTIVE | ||
); | ||
} | ||
|
||
public function toArray(): array | ||
{ | ||
return [ | ||
'id' => $this->id, | ||
'credits' => $this->credits, | ||
'creditsUsed' => $this->creditsUsed, | ||
'status' => $this->status, | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,121 @@ | ||||||||||||||||||||||||||||||||||||||||||
<?php | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
namespace Utopia\Pay\Discount; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
class Discount | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
public const TYPE_FIXED = 'fixed'; // Fixed amount discount | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public const TYPE_PERCENTAGE = 'percentage'; // Percentage discount | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||
* @param string $id | ||||||||||||||||||||||||||||||||||||||||||
* @param float $value | ||||||||||||||||||||||||||||||||||||||||||
* @param float $amount | ||||||||||||||||||||||||||||||||||||||||||
* @param string $description | ||||||||||||||||||||||||||||||||||||||||||
* @param string $type | ||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||
public function __construct(private string $id, private float $value, private float $amount, private string $description = '', private string $type = self::TYPE_FIXED) | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function getId(): string | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->id; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function setId(string $id): static | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$this->id = $id; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $this; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function getAmount(): float | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->amount; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function setAmount(float $amount): static | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$this->amount = $amount; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $this; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function getDescription(): string | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->description; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function setDescription(string $description): static | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$this->description = $description; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $this; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function getType(): string | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->type; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function setType(string $type): static | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$this->type = $type; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $this; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function getValue(): float | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->value; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function setValue(float $value): static | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$this->value = $value; | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $this; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function calculateDiscount(float $amount): float | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments to explain this method and what $amount is would be helpful |
||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
if ($this->type === self::TYPE_FIXED) { | ||||||||||||||||||||||||||||||||||||||||||
return min($this->amount, $amount); | ||||||||||||||||||||||||||||||||||||||||||
} elseif ($this->type === self::TYPE_PERCENTAGE) { | ||||||||||||||||||||||||||||||||||||||||||
return ($this->value / 100) * $amount; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+84
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if someone passes a negative value for amount? |
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return 0; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+82
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed discount calculation uses The calculation for TYPE_FIXED discounts uses For fixed discounts, both Consider using public function calculateDiscount(float $amount): float
{
if ($this->type === self::TYPE_FIXED) {
- return min($this->amount, $amount);
+ return min($this->value, $amount);
} elseif ($this->type === self::TYPE_PERCENTAGE) {
return ($this->value / 100) * $amount;
}
return 0;
} 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function isValid(): bool | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return $this->amount > 0 && $this->type === self::TYPE_FIXED || $this->value > 0 && $this->type === self::TYPE_PERCENTAGE; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public function toArray() | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
return [ | ||||||||||||||||||||||||||||||||||||||||||
'id' => $this->id, | ||||||||||||||||||||||||||||||||||||||||||
'amount' => $this->amount, | ||||||||||||||||||||||||||||||||||||||||||
'value' => $this->value, | ||||||||||||||||||||||||||||||||||||||||||
'description' => $this->description, | ||||||||||||||||||||||||||||||||||||||||||
'type' => $this->type, | ||||||||||||||||||||||||||||||||||||||||||
]; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
public static function fromArray($data) | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
$discount = new self( | ||||||||||||||||||||||||||||||||||||||||||
$data['id'] ?? $data['$id'] ?? '', | ||||||||||||||||||||||||||||||||||||||||||
$data['value'] ?? 0, | ||||||||||||||||||||||||||||||||||||||||||
$data['amount'] ?? 0, | ||||||||||||||||||||||||||||||||||||||||||
$data['description'] ?? '', | ||||||||||||||||||||||||||||||||||||||||||
$data['type'] ?? self::TYPE_FIXED, | ||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
return $discount; | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value and amount are a bit confusing. At the very least, this needs some comments to explain what they are.