diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index d47068c..aa82e99 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -33,8 +33,8 @@ "pid": "/sales/bill", "type": 3, "subtype": 1, - "name": "Archiv", - "uri": "{/prefix}sales/bill/archiv", + "name": "Archive", + "uri": "{/prefix}sales/bill/archive", "target": "self", "icon": null, "order": 1, @@ -94,8 +94,8 @@ "pid": "/purchase/bill", "type": 3, "subtype": 1, - "name": "Archiv", - "uri": "{/prefix}purchase/bill/archiv", + "name": "Archive", + "uri": "{/prefix}purchase/bill/archive", "target": "self", "icon": null, "order": 1, @@ -155,8 +155,8 @@ "pid": "/warehouse/bill", "type": 3, "subtype": 1, - "name": "Archiv", - "uri": "{/prefix}warehouse/bill/archiv", + "name": "Archive", + "uri": "{/prefix}warehouse/bill/archive", "target": "self", "icon": null, "order": 1, @@ -181,5 +181,20 @@ "children": [] } ] + }, + { + "id": 1005107001, + "pid": "/sales/analysis", + "type": 3, + "subtype": 1, + "name": "Bill", + "uri": "{/prefix}sales/analysis/bill", + "target": "self", + "icon": null, + "order": 5, + "from": "Billing", + "permission": { "permission": 2, "type": null, "element": null }, + "parent": 1001602001, + "children": [] } ] diff --git a/Admin/Install/db.json b/Admin/Install/db.json index da8d653..3285f7b 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -205,22 +205,22 @@ }, "billing_bill_gross": { "name": "billing_bill_gross", - "type": "INT", + "type": "BIGINT", "null": false }, "billing_bill_net": { "name": "billing_bill_net", - "type": "INT", + "type": "BIGINT", "null": false }, "billing_bill_costs": { "name": "billing_bill_costs", - "type": "INT", + "type": "BIGINT", "null": false }, "billing_bill_profit": { "name": "billing_bill_profit", - "type": "INT", + "type": "BIGINT", "null": false }, "billing_bill_currency": { @@ -385,19 +385,19 @@ }, "billing_bill_element_price_single_net": { "name": "billing_bill_element_price_single_net", - "type": "INT", + "type": "BIGINT", "null": true, "default": null }, "billing_bill_element_price_total_net": { "name": "billing_bill_element_price_total_net", - "type": "INT", + "type": "BIGINT", "null": true, "default": null }, "billing_bill_element_tax_price": { "name": "billing_bill_element_tax_price", - "type": "INT", + "type": "BIGINT", "null": true, "default": null }, @@ -415,13 +415,13 @@ }, "billing_bill_element_price_single_gross": { "name": "billing_bill_element_price_single_gross", - "type": "INT", + "type": "BIGINT", "null": true, "default": null }, "billing_bill_element_price_total_gross": { "name": "billing_bill_element_price_total_gross", - "type": "INT", + "type": "BIGINT", "null": true, "default": null }, diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 57b08f6..dd3c914 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -105,4 +105,15 @@ return [ ], ], ], + '^.*/sales/analysis/bill(\?.*|$)$' => [ + [ + 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewBillAnalysis', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::MODULE_NAME, + 'type' => PermissionType::READ, + 'state' => PermissionState::SALES_INVOICE, + ], + ], + ], ]; diff --git a/Controller/ApiController.php b/Controller/ApiController.php index e81f6b4..d9f0ca4 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -84,14 +84,16 @@ final class ApiController extends Controller */ public function createBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null) : Bill { + $account = null; if ($request->getData('client') !== null) { $account = ClientMapper::get((int) $request->getData('client')); } elseif ($request->getData('supplier') !== null) { $account = SupplierMapper::get((int) $request->getData('supplier')); } + /* @var \Modules\Account\Models\Account $account */ $bill = new Bill(); - $bill->setCreatedBy(new NullAccount($request->header->account)); + $bill->createdBy = new NullAccount($request->header->account); $bill->number = '{y}-{id}'; // @todo: use admin defined format $bill->billTo = $request->getData('billto') ?? ($account->profile->account->name1 . (!empty($account->profile->account->name2) ? ', ' . $account->profile->account->name2 : '')); // @todo: use defaultInvoiceAddress or mainAddress. also consider to use billto1, billto2, billto3 (for multiple lines e.g. name2, fao etc.) @@ -214,7 +216,7 @@ final class ApiController extends Controller * @param BillElement $element Bill element * @param int $type Change type (0 = update, -1 = remove, +1 = add) * - * @return BillElement + * @return Bill * * @since 1.0.0 */ diff --git a/Models/Bill.php b/Models/Bill.php index ea7ed01..6874743 100755 --- a/Models/Bill.php +++ b/Models/Bill.php @@ -17,6 +17,9 @@ namespace Modules\Billing\Models; use Modules\Admin\Models\Account; use Modules\Admin\Models\NullAccount; use Modules\Media\Models\Media; +use Modules\Media\Models\NullMedia; +use Modules\ClientManagement\Models\Client; +use Modules\SupplierManagement\Models\Supplier; use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\Money; @@ -67,7 +70,7 @@ class Bill implements \JsonSerializable /** * Bill created at. * - * @var \DateTime + * @var \DateTimeImmutable * @since 1.0.0 */ public \DateTimeImmutable $createdAt; @@ -96,9 +99,9 @@ class Bill implements \JsonSerializable */ public Account $createdBy; - public $client = 0; + public int | Client $client = 0; - public $supplier = 0; + public int | Supplier $supplier = 0; /** * Receiver. @@ -114,7 +117,7 @@ class Bill implements \JsonSerializable * @var string * @since 1.0.0 */ - private $shipFAO = ''; + public string $shipFAO = ''; /** * Shipping address. @@ -122,7 +125,7 @@ class Bill implements \JsonSerializable * @var string * @since 1.0.0 */ - private $shipAddress = ''; + public string $shipAddress = ''; /** * Shipping city. @@ -130,7 +133,7 @@ class Bill implements \JsonSerializable * @var string * @since 1.0.0 */ - private $shipCity = ''; + public string $shipCity = ''; /** * Shipping zip. @@ -138,7 +141,7 @@ class Bill implements \JsonSerializable * @var string * @since 1.0.0 */ - private $shipZip = ''; + public string $shipZip = ''; /** * Shipping country. @@ -146,7 +149,7 @@ class Bill implements \JsonSerializable * @var string * @since 1.0.0 */ - private $shipCountry = ''; + public string $shipCountry = ''; /** * Billing. @@ -199,12 +202,12 @@ class Bill implements \JsonSerializable /** * Person refering for this order. * - * @var int + * @var Account * @since 1.0.0 */ - private $referral; + public Account $referral; - private $referralName = ''; + public string $referralName = ''; public Money $net; @@ -214,27 +217,31 @@ class Bill implements \JsonSerializable public Money $profit; - private $currency = ISO4217CharEnum::_EUR; + public Money $insurance; - private $info = ''; + public Money $freight; - private $payment = 0; + private string $currency = ISO4217CharEnum::_EUR; - private $paymentText = ''; + public string $info = ''; - private $terms = 0; + public $payment = 0; - private $termsText = ''; + public string $paymentText = ''; - private $shipping = 0; + public $terms = 0; - private $shippingText = ''; + public string $termsText = ''; - private $vouchers = []; + public $shipping = 0; - private $trackings = []; + public string $shippingText = ''; - private $elements = []; + private array $vouchers = []; + + private array $trackings = []; + + private array $elements = []; /** * Reference to other Bill (delivery note/credit note etc). @@ -267,33 +274,7 @@ class Bill implements \JsonSerializable $this->createdAt = new \DateTimeImmutable(); $this->performanceDate = new \DateTime(); $this->createdBy = new NullAccount(); - $this->referer = new NullAccount(); - } - - /** - * Get created by - * - * @return Account - * - * @since 1.0.0 - */ - public function getCreatedBy() : Account - { - return $this->createdBy; - } - - /** - * Set created by - * - * @param Account $account Created by - * - * @return void - * - * @since 1.0.0 - */ - public function setCreatedBy(Account $account) : void - { - $this->createdBy = $account; + $this->referral = new NullAccount(); } /** @@ -332,7 +313,7 @@ class Bill implements \JsonSerializable $this->createdAt->format('m'), $this->createdAt->format('d'), $this->id, - $this->type->getId(), + \is_int($this->type) ? $this->type : $this->type->getId(), ], $number ); @@ -355,11 +336,11 @@ class Bill implements \JsonSerializable /** * Get type * - * @return int + * @return int | BillType * * @since 1.0.0 */ - public function getType() : int + public function getType() : int | BillType { return $this->type; } @@ -367,13 +348,13 @@ class Bill implements \JsonSerializable /** * Set type * - * @param int $type Type + * @param int|BillType $type Type * * @return void * * @since 1.0.0 */ - public function setType(int $type) : void + public function setType(int | BillType $type) : void { $this->type = $type; } @@ -404,18 +385,6 @@ class Bill implements \JsonSerializable $this->status = $status; } - /** - * Get created at date time - * - * @return \DateTime - * - * @since 1.0.0 - */ - public function getCreatedAt() : \DateTime - { - return $this->createdAt; - } - /** * Set shipping date. * @@ -780,136 +749,6 @@ class Bill implements \JsonSerializable return $this->billCountry; } - /** - * Set referer. - * - * @param int $referer Referer - * - * @return void - * - * @since 1.0.0 - */ - public function setReferer(int $referer) : void - { - $this->referer = $referer; - } - - /** - * Get referer. - * - * @return int - * - * @since 1.0.0 - */ - public function getReferer() : int - { - return $this->referer; - } - - /** - * Set referer name. - * - * @param string $refererName Referer name - * - * @return void - * - * @since 1.0.0 - */ - public function setRefererName(string $refererName) : void - { - $this->refererName = $refererName; - } - - /** - * Get referer name. - * - * @return string - * - * @since 1.0.0 - */ - public function getRefererName() : string - { - return $this->refererName; - } - - /** - * Set tax id. - * - * @param string $tax Tax id - * - * @return void - * - * @since 1.0.0 - */ - public function setTaxId(string $tax) : void - { - $this->taxId = $tax; - } - - /** - * Get tax id. - * - * @return string - * - * @since 1.0.0 - */ - public function getTaxId() : string - { - return $this->taxId; - } - - /** - * Set insurance. - * - * @param Money $insurance Insurance fee - * - * @return void - * - * @since 1.0.0 - */ - public function setInsurance(Money $insurance) : void - { - $this->insurance = $insurance; - } - - /** - * Get insurance. - * - * @return Money - * - * @since 1.0.0 - */ - public function getInsurance() : Money - { - return $this->insurance; - } - - /** - * Set freight. - * - * @param Money $freight Freight fee - * - * @return void - * - * @since 1.0.0 - */ - public function setFreight(Money $freight) : void - { - $this->freight = $freight; - } - - /** - * Get freight. - * - * @return Money - * - * @since 1.0.0 - */ - public function getFreight() : Money - { - return $this->freight; - } - /** * Get net amount. * diff --git a/Models/BillElement.php b/Models/BillElement.php index 41ecb03..7d393cc 100755 --- a/Models/BillElement.php +++ b/Models/BillElement.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\Billing\Models; use phpOMS\Localization\Money; +use phpOMS\Stdlib\Base\FloatInt; /** * Bill class. @@ -34,9 +35,9 @@ class BillElement implements \JsonSerializable */ protected int $id = 0; - private int $order = 0; + public int $order = 0; - public $item = null; + public ?int $item = null; public string $itemNumber = ''; @@ -50,35 +51,35 @@ class BillElement implements \JsonSerializable public Money $totalSalesPriceNet; - private $singleDiscountP = null; + public ?FloatInt $singleDiscountP = null; - private $totalDiscountP = null; + public ?FloatInt $totalDiscountP = null; - private $singleDiscountR = 0; + public ?FloatInt $singleDiscountR = null; - private $discountQ = 0; + public ?FloatInt $discountQ = null; - private $singlePriceNet = null; + public ?FloatInt $singlePriceNet = null; - private $totalPriceNet = null; + public ?FloatInt $totalPriceNet = null; public Money $singlePurchasePriceNet; public Money $totalPurchasePriceNet; - private $taxP = null; + public ?FloatInt $taxP = null; - private $taxR = 0.0; + public ?FloatInt $taxR = null; - private $singleSalesPriceGross = null; + public ?FloatInt $singleSalesPriceGross = null; - private $totalSalesPriceGross = null; + public ?FloatInt $totalSalesPriceGross = null; - private $event = 0; + public $event = 0; - private $promotion = 0; + public $promotion = 0; - public $bill = 0; + public int | Bill $bill = 0; public function __construct() { @@ -193,370 +194,6 @@ class BillElement implements \JsonSerializable $this->item = $item; } - /** - * Set item name. - * - * @param string $name Name - * - * @return void - * - * @since 1.0.0 - */ - public function setItemName(string $name) : void - { - $this->itemName = $name; - } - - /** - * Get item name. - * - * @return string - * - * @since 1.0.0 - */ - public function getItemName() : string - { - return $this->itemName; - } - - /** - * Set item description. - * - * @param string $description Description - * - * @return void - * - * @since 1.0.0 - */ - public function setItemDescription(string $description) : void - { - $this->itemDescription = $description; - } - - /** - * Get item description. - * - * @return string - * - * @since 1.0.0 - */ - public function getItemDescripion() : string - { - return $this->itemDescription; - } - - /** - * Set single unit price. - * - * @param Money $price Single unit price - * - * @return void - * - * @since 1.0.0 - */ - public function setSinglePrice(Money $price) : void - { - $this->singlePrice = $price; - } - - /** - * Get single unit price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getSinglePrice() : ?Money - { - return $this->singlePrice; - } - - /** - * Set total price. - * - * @param Money $price Total price - * - * @return void - * - * @since 1.0.0 - */ - public function setTotalPrice(Money $price) : void - { - $this->totalPrice = $price; - } - - /** - * Get total price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getTotalPrice() : ?Money - { - return $this->totalPrice; - } - - /** - * Set discount price. - * - * @param Money $discount Discount - * - * @return void - * - * @since 1.0.0 - */ - public function setDiscountPrice(Money $discount) : void - { - $this->singleDiscountP = $discount; - } - - /** - * Get discount price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getDiscountPrice() : ?Money - { - return $this->singleDiscountP; - } - - /** - * Set total discount price. - * - * @param Money $discount Discount price - * - * @return void - * - * @since 1.0.0 - */ - public function setTotalDiscountPrice(Money $discount) : void - { - $this->totalDiscountP = $discount; - } - - /** - * Get total discount price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getTotalDiscountPrice() : ?Money - { - return $this->totalDiscountP; - } - - /** - * Set discount percentage. - * - * @param float $discount Discount percentag - * - * @return void - * - * @since 1.0.0 - */ - public function setDiscountPercentage(float $discount) : void - { - $this->singleDiscountR = $discount; - } - - /** - * Get discount percentage. - * - * @return float - * - * @since 1.0.0 - */ - public function getDiscountPercentage() : float - { - return $this->singleDiscountR; - } - - /** - * Set discount quantity. - * - * @param int|float $quantity Quantity - * - * @return void - * - * @since 1.0.0 - */ - public function setDiscountQuantity($quantity) : void - { - $this->discountQ = $quantity; - } - - /** - * Get discount quantity. - * - * @return int|float - * - * @since 1.0.0 - */ - public function getDiscountQuantity() - { - return $this->discountQ; - } - - /** - * Set single net price. - * - * @param Money $price Net price - * - * @return void - * - * @since 1.0.0 - */ - public function setSingleNetPrice(Money $price) : void - { - $this->singlePriceNet = $price; - } - - /** - * Get single net price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getSingleNetPrice() : ?Money - { - return $this->singlePriceNet; - } - - /** - * Set total net price. - * - * @param Money $price Total net price - * - * @return void - * - * @since 1.0.0 - */ - public function setTotalNetPrice(Money $price) : void - { - $this->totalPriceNet = $price; - } - - /** - * Get total net price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getTotalNetPrice() : ?Money - { - return $this->totalPriceNet; - } - - /** - * Set tax price. - * - * @param Money $tax Tax price - * - * @return void - * - * @since 1.0.0 - */ - public function setTaxPrice(Money $tax) : void - { - $this->taxP = $tax; - } - - /** - * Get tax price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getTaxPrice() : ?Money - { - return $this->taxP; - } - - /** - * Set tax rate. - * - * @param float $tax Tax rate - * - * @return void - * - * @since 1.0.0 - */ - public function setTaxPercentage(float $tax) : void - { - $this->taxR = $tax; - } - - /** - * Get tax rate. - * - * @return float - * - * @since 1.0.0 - */ - public function getTaxPercentage() : float - { - return $this->taxR; - } - - /** - * Set single gross price. - * - * @param Money $price Single gross price - * - * @return void - * - * @since 1.0.0 - */ - public function setSingleGrossPrice(Money $price) : void - { - $this->singlePriceGross = $price; - } - - /** - * Get single gross price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getSingleGrossPrice() : ?Money - { - return $this->singlePriceGross; - } - - /** - * Set total gross price. - * - * @param Money $price Total gross price - * - * @return void - * - * @since 1.0.0 - */ - public function setTotalGrossPrice(Money $price) : void - { - $this->totalPriceGross = $price; - } - - /** - * Get total gross price. - * - * @return null|Money - * - * @since 1.0.0 - */ - public function getTotalGrossPrice() : ?Money - { - return $this->totalPriceGross; - } - /** * {@inheritdoc} */ diff --git a/Models/BillType.php b/Models/BillType.php index 789cf5d..d6239f2 100755 --- a/Models/BillType.php +++ b/Models/BillType.php @@ -41,9 +41,9 @@ class BillType /** * Localization * - * @var int|int[]|BillTypeL11n|BillTypeL11n[] + * @var string|BillTypeL11n */ - protected $l11n = 0; + protected string | BillTypeL11n $l11n; /** * Constructor. diff --git a/Models/BillTypeL11n.php b/Models/BillTypeL11n.php index 71a4e51..df51dfd 100755 --- a/Models/BillTypeL11n.php +++ b/Models/BillTypeL11n.php @@ -110,7 +110,7 @@ BillType $type = 0; * * @since 1.0.0 */ - public function getType() : int + public function getType() : int | BillType { return $this->type; } diff --git a/Models/PurchaseBillMapper.php b/Models/PurchaseBillMapper.php index 51449cd..972f250 100644 --- a/Models/PurchaseBillMapper.php +++ b/Models/PurchaseBillMapper.php @@ -150,10 +150,12 @@ final class PurchaseBillMapper extends BillMapper public static function getItemRetentionRate(int $id, \DateTime $start, \DateTime $end) : float { + return 0.0; } public static function getItemLivetimeValue(int $id, \DateTime $start, \DateTime $end) : Money { + return new Money(); } public static function getNewestItemInvoices(int $id, int $limit = 10) : array diff --git a/Models/SalesBillMapper.php b/Models/SalesBillMapper.php index 0a38ac6..2ff8354 100644 --- a/Models/SalesBillMapper.php +++ b/Models/SalesBillMapper.php @@ -150,10 +150,12 @@ final class SalesBillMapper extends BillMapper public static function getItemRetentionRate(int $id, \DateTime $start, \DateTime $end) : float { + return 0.0; } public static function getItemLivetimeValue(int $id, \DateTime $start, \DateTime $end) : Money { + return new Money(); } public static function getNewestItemInvoices(int $id, int $limit = 10) : array @@ -219,6 +221,48 @@ final class SalesBillMapper extends BillMapper return [$clients, $data]; } + public static function getItemBills(int $id, \DateTime $start, \DateTime $end) : array + { + $depth = 3; + + // @todo: limit is not working correctly... only returns / 2 or something like that?. Maybe because bills arent unique? + + $query ??= self::getQuery(null, [], RelationType::ALL, $depth); + $query->leftJoin(BillElementMapper::getTable(), BillElementMapper::getTable() . '_' . $depth) + ->on(self::$table . '_' . $depth . '.billing_bill_id', '=', BillElementMapper::getTable() . '_' . $depth . '.billing_bill_element_bill') + ->where(BillElementMapper::getTable() . '_' . $depth . '.billing_bill_element_item', '=', $id) + ->limit($limit = 10); + + if (!empty(self::$createdAt)) { + $query->orderBy(self::$table . '_' . $depth . '.' . self::$columns[self::$createdAt]['name'], 'DESC'); + } else { + $query->orderBy(self::$table . '_' . $depth . '.' . self::$columns[self::$primaryField]['name'], 'DESC'); + } + + return self::getAllByQuery($query, RelationType::ALL, $depth); + } + + public static function getClientItem(int $client, \DateTime $start, \DateTime $end) : array + { + $depth = 3; + + // @todo: limit is not working correctly... only returns / 2 or something like that?. Maybe because bills arent unique? + + $query ??= BillElementMapper::getQuery(null, [], RelationType::ALL, $depth); + $query->leftJoin(self::$table, self::$table . '_' . $depth) + ->on(BillElementMapper::getTable() . '_' . $depth . '.billing_bill_element_bill', '=', self::$table . '_' . $depth . '.billing_bill_id') + ->where(self::$table . '_' . $depth . '.billing_bill_client', '=', $client) + ->limit($limit = 10); + + if (!empty(self::$createdAt)) { + $query->orderBy(self::$table . '_' . $depth . '.' . self::$columns[self::$createdAt]['name'], 'DESC'); + } else { + $query->orderBy(self::$table . '_' . $depth . '.' . self::$columns[self::$primaryField]['name'], 'DESC'); + } + + return BillElementMapper::getAllByQuery($query, RelationType::ALL, $depth); + } + public static function getItemRegionSales(int $id, \DateTime $start, \DateTime $end) : array { $query = new Builder(self::$db); diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index 445efb8..0b50238 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -13,5 +13,6 @@ declare(strict_types=1); return ['Navigation' => [ + 'Archive' => 'Archive', 'Billing' => 'Billing', ]]; diff --git a/Theme/Backend/purchase-bill-list.tpl.php b/Theme/Backend/purchase-bill-list.tpl.php index 464e294..abd8593 100755 --- a/Theme/Backend/purchase-bill-list.tpl.php +++ b/Theme/Backend/purchase-bill-list.tpl.php @@ -133,18 +133,6 @@ echo $this->getData('nav')->render(); ?> - getHtml('Gross'); ?> - - - getHtml('Profit'); ?>