diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json
index 010a3f4..58576b4 100755
--- a/Admin/Install/Navigation.install.json
+++ b/Admin/Install/Navigation.install.json
@@ -5,7 +5,7 @@
"type": 2,
"subtype": 1,
"name": "Billing",
- "uri": "{/prefix}sales/invoice/list",
+ "uri": "{/prefix}sales/bill/list",
"target": "self",
"icon": null,
"order": 5,
@@ -15,11 +15,11 @@
"children": [
{
"id": 1005104101,
- "pid": "/sales/invoice",
+ "pid": "/sales/bill",
"type": 3,
"subtype": 1,
"name": "List",
- "uri": "{/prefix}sales/invoice/list",
+ "uri": "{/prefix}sales/bill/list",
"target": "self",
"icon": null,
"order": 1,
@@ -30,11 +30,11 @@
},
{
"id": 1005104301,
- "pid": "/sales/invoice",
+ "pid": "/sales/bill",
"type": 3,
"subtype": 1,
"name": "Create",
- "uri": "{/prefix}sales/invoice/create?{?}",
+ "uri": "{/prefix}sales/bill/create?{?}",
"target": "self",
"icon": null,
"order": 5,
@@ -50,22 +50,22 @@
"pid": "/",
"type": 2,
"subtype": 1,
- "name": "Invoice",
- "uri": "{/prefix}purchase/invoice/list",
+ "name": "Billing",
+ "uri": "{/prefix}purchase/bill/list",
"target": "self",
"icon": null,
"order": 5,
- "from": "Invoice",
+ "from": "Billing",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1002101001,
"children": [
{
"id": 1005105101,
- "pid": "/purchase/invoice",
+ "pid": "/purchase/bill",
"type": 3,
"subtype": 1,
"name": "List",
- "uri": "{/prefix}purchase/invoice/list",
+ "uri": "{/prefix}purchase/bill/list",
"target": "self",
"icon": null,
"order": 1,
@@ -76,11 +76,11 @@
},
{
"id": 1005105301,
- "pid": "/purchase/invoice",
+ "pid": "/purchase/bill",
"type": 3,
"subtype": 1,
"name": "Create",
- "uri": "{/prefix}purchase/invoice/create?{?}",
+ "uri": "{/prefix}purchase/bill/create?{?}",
"target": "self",
"icon": null,
"order": 5,
diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php
index cb13ef9..e123f49 100755
--- a/Admin/Routes/Web/Backend.php
+++ b/Admin/Routes/Web/Backend.php
@@ -6,9 +6,9 @@ use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
- '^.*/sales/invoice/create.*$' => [
+ '^.*/sales/bill/create.*$' => [
[
- 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingInvoiceCreate',
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingSalesInvoiceCreate',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@@ -17,9 +17,9 @@ return [
],
],
],
- '^.*/sales/invoice/list.*$' => [
+ '^.*/sales/bill/list.*$' => [
[
- 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingInvoiceList',
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingSalesList',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@@ -28,9 +28,9 @@ return [
],
],
],
- '^.*/sales/invoice\?.*$' => [
+ '^.*/sales/bill\?.*$' => [
[
- 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingInvoice',
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingSalesInvoice',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@@ -39,7 +39,7 @@ return [
],
],
],
- '^.*/purchase/invoice/create.*$' => [
+ '^.*/purchase/bill/create.*$' => [
[
'dest' => '\Modules\Billing\Controller\BackendController:viewBillingPurchaseInvoiceCreate',
'verb' => RouteVerb::GET,
@@ -50,9 +50,9 @@ return [
],
],
],
- '^.*/purchase/invoice/list.*$' => [
+ '^.*/purchase/bill/list.*$' => [
[
- 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingPurchaInvoiceList',
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingPurchaseList',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@@ -61,4 +61,15 @@ return [
],
],
],
+ '^.*/purchase/bill\?.*$' => [
+ [
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillingPurchaseInvoice',
+ 'verb' => RouteVerb::GET,
+ 'permission' => [
+ 'module' => BackendController::MODULE_NAME,
+ 'type' => PermissionType::READ,
+ 'state' => PermissionState::SALES_INVOICE,
+ ],
+ ],
+ ],
];
diff --git a/Controller/BackendController.php b/Controller/BackendController.php
index b0a8057..6ee6ae1 100755
--- a/Controller/BackendController.php
+++ b/Controller/BackendController.php
@@ -14,7 +14,8 @@ declare(strict_types=1);
namespace Modules\Billing\Controller;
-use Modules\Billing\Models\BillMapper;
+use Modules\Billing\Models\SalesBillMapper;
+use Modules\Billing\Models\PurchaseBillMapper;
use Modules\Billing\Models\BillTypeL11n;
use phpOMS\Contract\RenderableInterface;
use phpOMS\Message\RequestAbstract;
@@ -43,7 +44,7 @@ final class BackendController extends Controller
* @since 1.0.0
* @codeCoverageIgnore
*/
- public function viewBillingInvoiceList(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
+ public function viewBillingSalesList(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Billing/Theme/Backend/sales-bill-list');
@@ -51,18 +52,18 @@ final class BackendController extends Controller
if ($request->getData('ptype') === 'p') {
$view->setData('bills',
- BillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
- ::getBeforePivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
+ SalesBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getSalesBeforePivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
);
} elseif ($request->getData('ptype') === 'n') {
$view->setData('bills',
- BillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
- ::getAfterPivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
+ SalesBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getSalesAfterPivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
);
} else {
$view->setData('bills',
- BillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
- ::getAfterPivot(0, limit: 25, depth: 3)
+ SalesBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getSalesAfterPivot(0, limit: 25, depth: 3)
);
}
@@ -81,13 +82,13 @@ final class BackendController extends Controller
* @since 1.0.0
* @codeCoverageIgnore
*/
- public function viewBillingInvoice(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
+ public function viewBillingSalesInvoice(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Billing/Theme/Backend/sales-bill');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response));
- $bill = BillMapper::get((int) $request->getData('id'));
+ $bill = SalesBillMapper::get((int) $request->getData('id'));
$view->setData('bill', $bill);
@@ -106,7 +107,7 @@ final class BackendController extends Controller
* @since 1.0.0
* @codeCoverageIgnore
*/
- public function viewBillingInvoiceCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
+ public function viewBillingSalesInvoiceCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Billing/Theme/Backend/invoice-create');
@@ -127,11 +128,53 @@ final class BackendController extends Controller
* @since 1.0.0
* @codeCoverageIgnore
*/
- public function viewBillingPurchaInvoiceList(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
+ public function viewBillingPurchaseList(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
- $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-invoice-list');
- $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005105001, $request, $response));
+ $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill-list');
+ $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response));
+
+ if ($request->getData('ptype') === 'p') {
+ $view->setData('bills',
+ PurchaseBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getPurchaseBeforePivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
+ );
+ } elseif ($request->getData('ptype') === 'n') {
+ $view->setData('bills',
+ PurchaseBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getPurchaseAfterPivot((int) ($request->getData('id') ?? 0), limit: 25, depth: 3)
+ );
+ } else {
+ $view->setData('bills',
+ PurchaseBillMapper::withConditional('language', $response->getLanguage(), [BillTypeL11n::class])
+ ::getPurchaseAfterPivot(0, limit: 25, depth: 3)
+ );
+ }
+
+ return $view;
+ }
+
+ /**
+ * Routing end-point for application behaviour.
+ *
+ * @param RequestAbstract $request Request
+ * @param ResponseAbstract $response Response
+ * @param mixed $data Generic data
+ *
+ * @return RenderableInterface
+ *
+ * @since 1.0.0
+ * @codeCoverageIgnore
+ */
+ public function viewBillingPurchaseInvoice(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
+ {
+ $view = new View($this->app->l11nManager, $request, $response);
+ $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill');
+ $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response));
+
+ $bill = PurchaseBillMapper::get((int) $request->getData('id'));
+
+ $view->setData('bill', $bill);
return $view;
}
diff --git a/Models/BillMapper.php b/Models/BillMapper.php
index 79427e8..ad6497b 100755
--- a/Models/BillMapper.php
+++ b/Models/BillMapper.php
@@ -32,7 +32,7 @@ use phpOMS\Localization\Money;
* @link https://orange-management.org
* @since 1.0.0
*/
-final class BillMapper extends DataMapperAbstract
+class BillMapper extends DataMapperAbstract
{
/**
* Columns.
@@ -153,235 +153,4 @@ final class BillMapper extends DataMapperAbstract
* @since 1.0.0
*/
protected static string $table = 'billing_bill';
-
- public static function getSalesByItemId(int $id, \DateTime $start, \DateTime $end) : Money
- {
- $query = new Builder(self::$db);
- $result = $query->select('SUM(billing_bill_element_total_salesprice_net)')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->execute()
- ->fetch();
-
- return new Money((int) $result[0]);
- }
-
- public static function getSalesByClientId(int $id, \DateTime $start, \DateTime $end) : Money
- {
- $query = new Builder(self::$db);
- $result = $query->select('SUM(billing_bill_net)')
- ->from(self::$table)
- ->where(self::$table . '.billing_bill_client', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->execute()
- ->fetch();
-
- return new Money((int) $result[0]);
- }
-
- public static function getAvgSalesPriceByItemId(int $id, \DateTime $start, \DateTime $end) : Money
- {
- $query = new Builder(self::$db);
- $result = $query->select('SUM(billing_bill_element_single_salesprice_net)', 'COUNT(billing_bill_element_total_salesprice_net)')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->execute()
- ->fetch();
-
- return new Money((int) (((int) $result[0]) / ((int) $result[1])));
- }
-
- public static function getLastOrderDateByItemId(int $id) : \DateTimeImmutable
- {
- // @todo: only delivers/invoice/production (no offers ...)
- $query = new Builder(self::$db);
- $result = $query->select('billing_bill_performance_date')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->orderBy('billing_bill_id', 'DESC')
- ->limit(1)
- ->execute()
- ->fetch();
-
- return new \DateTimeImmutable($result[0]);
- }
-
- public static function getLastOrderDateByClientId(int $id) : \DateTimeImmutable
- {
- // @todo: only delivers/invoice/production (no offers ...)
- $query = new Builder(self::$db);
- $result = $query->select('billing_bill_performance_date')
- ->from(self::$table)
- ->where(self::$table . '.billing_bill_client', '=', $id)
- ->orderBy('billing_bill_id', 'DESC')
- ->limit(1)
- ->execute()
- ->fetch();
-
- return new \DateTimeImmutable($result[0]);
- }
-
- public static function getItemRetentionRate(int $id, \DateTime $start, \DateTime $end) : float
- {
- }
-
- public static function getItemLivetimeValue(int $id, \DateTime $start, \DateTime $end) : Money
- {
- }
-
- public static function getNewestItemInvoices(int $id, int $limit = 10) : 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);
-
- 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 getNewestClientInvoices(int $id, int $limit = 10) : 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->where(self::$table . '_' . $depth . '.billing_bill_client', '=', $id)
- ->limit($limit);
-
- 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 getItemTopCustomers(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
- {
- $depth = 3;
-
- $query ??= ClientMapper::getQuery(null, [], RelationType::ALL, $depth);
- $query->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
- ->leftJoin(self::$table, self::$table . '_' . $depth)
- ->on(ClientMapper::getTable() . '_' . $depth . '.clientmgmt_client_id', '=', self::$table . '_' . $depth . '.billing_bill_client')
- ->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)
- ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '<=', $end)
- ->orderBy('net_sales', 'DESC')
- ->limit($limit)
- ->groupBy(ClientMapper::getTable() . '_' . $depth . '.clientmgmt_client_id');
-
- $clients = ClientMapper::getAllByQuery($query, RelationType::ALL, $depth);
- $data = ClientMapper::getDataLastQuery();
-
- return [$clients, $data];
- }
-
- public static function getItemRegionSales(int $id, \DateTime $start, \DateTime $end) : array
- {
- $query = new Builder(self::$db);
- $result = $query->select(CountryMapper::getTable() . '.country_region')
- ->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->leftJoin(CountryMapper::getTable())
- ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->groupBy(CountryMapper::getTable() . '.country_region')
- ->execute()
- ->fetchAll(\PDO::FETCH_KEY_PAIR);
-
- return $result;
- }
-
- public static function getItemCountrySales(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
- {
- $query = new Builder(self::$db);
- $result = $query->select(CountryMapper::getTable() . '.country_code2')
- ->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->leftJoin(CountryMapper::getTable())
- ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->groupBy(CountryMapper::getTable() . '.country_code2')
- ->orderBy('net_sales', 'DESC')
- ->limit($limit)
- ->execute()
- ->fetchAll(\PDO::FETCH_KEY_PAIR);
-
- return $result;
- }
-
- public static function getItemMonthlySalesCosts(int $id, \DateTime $start, \DateTime $end) : array
- {
- $query = new Builder(self::$db);
- $result = $query->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
- ->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_costs')
- ->selectAs('YEAR(billing_bill_performance_date)', 'year')
- ->selectAs('MONTH(billing_bill_performance_date)', 'month')
- ->from(self::$table)
- ->leftJoin(BillElementMapper::getTable())
- ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
- ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->groupBy('year', 'month')
- ->orderBy(['year', 'month'], ['ASC', 'ASC'])
- ->execute()
- ->fetchAll();
-
- return $result;
- }
-
- public static function getClientMonthlySalesCosts(int $id, \DateTime $start, \DateTime $end) : array
- {
- $query = new Builder(self::$db);
- $result = $query->selectAs('SUM(billing_bill_net)', 'net_sales')
- ->selectAs('SUM(billing_bill_costs)', 'net_costs')
- ->selectAs('YEAR(billing_bill_performance_date)', 'year')
- ->selectAs('MONTH(billing_bill_performance_date)', 'month')
- ->from(self::$table)
- ->where(self::$table . '.billing_bill_client', '=', $id)
- ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
- ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
- ->groupBy('year', 'month')
- ->orderBy(['year', 'month'], ['ASC', 'ASC'])
- ->execute()
- ->fetchAll();
-
- return $result;
- }
}
diff --git a/Models/PurchaseBillMapper.php b/Models/PurchaseBillMapper.php
new file mode 100644
index 0000000..20b4972
--- /dev/null
+++ b/Models/PurchaseBillMapper.php
@@ -0,0 +1,335 @@
+where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::PURCHASE);
+
+ return self::getBeforePivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getStockBeforePivot(
+ mixed $pivot,
+ string $column = null,
+ int $limit = 50,
+ string $order = 'ASC',
+ int $relations = RelationType::ALL,
+ int $depth = 3,
+ Builder $query = null
+ ) : array
+ {
+ $query = self::getQuery(null, [], $relations, $depth);
+ $query->where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::STOCK);
+
+ return self::getBeforePivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getPurchaseAfterPivot(
+ mixed $pivot,
+ string $column = null,
+ int $limit = 50,
+ string $order = 'ASC',
+ int $relations = RelationType::ALL,
+ int $depth = 3,
+ Builder $query = null
+ ) : array
+ {
+ $query = self::getQuery(null, [], $relations, $depth);
+ $query->where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::PURCHASE);
+
+ return self::getAfterPivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getStockAfterPivot(
+ mixed $pivot,
+ string $column = null,
+ int $limit = 50,
+ string $order = 'ASC',
+ int $relations = RelationType::ALL,
+ int $depth = 3,
+ Builder $query = null
+ ) : array
+ {
+ $query = self::getQuery(null, [], $relations, $depth);
+ $query->where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::STOCK);
+
+ return self::getAfterPivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getPurchaseByItemId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_element_total_purchaseprice_net)')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) $result[0]);
+ }
+
+ public static function getPurchaseBySupplierId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_net)')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_supplier', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) $result[0]);
+ }
+
+ public static function getAvgPurchasePriceByItemId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_element_single_purchaseprice_net)', 'COUNT(billing_bill_element_total_purchaseprice_net)')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) (((int) $result[0]) / ((int) $result[1])));
+ }
+
+ public static function getLastOrderDateByItemId(int $id) : \DateTimeImmutable
+ {
+ // @todo: only delivers/invoice/production (no offers ...)
+ $query = new Builder(self::$db);
+ $result = $query->select('billing_bill_performance_date')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->orderBy('billing_bill_id', 'DESC')
+ ->limit(1)
+ ->execute()
+ ->fetch();
+
+ return new \DateTimeImmutable($result[0]);
+ }
+
+ public static function getLastOrderDateBySupplierId(int $id) : \DateTimeImmutable
+ {
+ // @todo: only delivers/invoice/production (no offers ...)
+ $query = new Builder(self::$db);
+ $result = $query->select('billing_bill_performance_date')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_supplier', '=', $id)
+ ->orderBy('billing_bill_id', 'DESC')
+ ->limit(1)
+ ->execute()
+ ->fetch();
+
+ return new \DateTimeImmutable($result[0]);
+ }
+
+ public static function getItemRetentionRate(int $id, \DateTime $start, \DateTime $end) : float
+ {
+ }
+
+ public static function getItemLivetimeValue(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ }
+
+ public static function getNewestItemInvoices(int $id, int $limit = 10) : 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);
+
+ 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 getNewestSupplierInvoices(int $id, int $limit = 10) : 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->where(self::$table . '_' . $depth . '.billing_bill_supplier', '=', $id)
+ ->limit($limit);
+
+ 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 getItemTopSuppliers(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
+ {
+ $depth = 3;
+
+ $query ??= SupplierMapper::getQuery(null, [], RelationType::ALL, $depth);
+ $query->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_purchase')
+ ->leftJoin(self::$table, self::$table . '_' . $depth)
+ ->on(SupplierMapper::getTable() . '_' . $depth . '.suppliermgmt_supplier_id', '=', self::$table . '_' . $depth . '.billing_bill_supplier')
+ ->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)
+ ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '<=', $end)
+ ->orderBy('net_purchase', 'DESC')
+ ->limit($limit)
+ ->groupBy(SupplierMapper::getTable() . '_' . $depth . '.suppliermgmt_supplier_id');
+
+ $suppliers = SupplierMapper::getAllByQuery($query, RelationType::ALL, $depth);
+ $data = SupplierMapper::getDataLastQuery();
+
+ return [$suppliers, $data];
+ }
+
+ public static function getItemRegionPurchase(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select(CountryMapper::getTable() . '.country_region')
+ ->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_purchase')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->leftJoin(CountryMapper::getTable())
+ ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy(CountryMapper::getTable() . '.country_region')
+ ->execute()
+ ->fetchAll(\PDO::FETCH_KEY_PAIR);
+
+ return $result;
+ }
+
+ public static function getItemCountryPurchase(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select(CountryMapper::getTable() . '.country_code2')
+ ->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_purchase')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->leftJoin(CountryMapper::getTable())
+ ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy(CountryMapper::getTable() . '.country_code2')
+ ->orderBy('net_purchase', 'DESC')
+ ->limit($limit)
+ ->execute()
+ ->fetchAll(\PDO::FETCH_KEY_PAIR);
+
+ return $result;
+ }
+
+ public static function getItemMonthlyPurchaseCosts(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_purchase')
+ ->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_costs')
+ ->selectAs('YEAR(billing_bill_performance_date)', 'year')
+ ->selectAs('MONTH(billing_bill_performance_date)', 'month')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy('year', 'month')
+ ->orderBy(['year', 'month'], ['ASC', 'ASC'])
+ ->execute()
+ ->fetchAll();
+
+ return $result;
+ }
+
+ public static function getSupplierMonthlyPurchaseCosts(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->selectAs('SUM(billing_bill_net)', 'net_purchase')
+ ->selectAs('SUM(billing_bill_costs)', 'net_costs')
+ ->selectAs('YEAR(billing_bill_performance_date)', 'year')
+ ->selectAs('MONTH(billing_bill_performance_date)', 'month')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_supplier', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy('year', 'month')
+ ->orderBy(['year', 'month'], ['ASC', 'ASC'])
+ ->execute()
+ ->fetchAll();
+
+ return $result;
+ }
+}
diff --git a/Models/SalesBillMapper.php b/Models/SalesBillMapper.php
new file mode 100644
index 0000000..9621f87
--- /dev/null
+++ b/Models/SalesBillMapper.php
@@ -0,0 +1,303 @@
+where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::SALES);
+
+ return self::getBeforePivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getSalesAfterPivot(
+ mixed $pivot,
+ string $column = null,
+ int $limit = 50,
+ string $order = 'ASC',
+ int $relations = RelationType::ALL,
+ int $depth = 3,
+ Builder $query = null
+ ) : array
+ {
+ $query = self::getQuery(null, [], $relations, $depth);
+ $query->where(BillTypeMapper::getTable() . '_' . ($depth - 1) . '.billing_type_transfer_type', '=', BillTransferType::SALES);
+
+ return self::getAfterPivot($pivot, $column, $limit, $order, $relations, $depth, $query);
+ }
+
+ public static function getSalesByItemId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_element_total_salesprice_net)')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) $result[0]);
+ }
+
+ public static function getSalesByClientId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_net)')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_client', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) $result[0]);
+ }
+
+ public static function getAvgSalesPriceByItemId(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select('SUM(billing_bill_element_single_salesprice_net)', 'COUNT(billing_bill_element_total_salesprice_net)')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->execute()
+ ->fetch();
+
+ return new Money((int) (((int) $result[0]) / ((int) $result[1])));
+ }
+
+ public static function getLastOrderDateByItemId(int $id) : \DateTimeImmutable
+ {
+ // @todo: only delivers/invoice/production (no offers ...)
+ $query = new Builder(self::$db);
+ $result = $query->select('billing_bill_performance_date')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->orderBy('billing_bill_id', 'DESC')
+ ->limit(1)
+ ->execute()
+ ->fetch();
+
+ return new \DateTimeImmutable($result[0]);
+ }
+
+ public static function getLastOrderDateByClientId(int $id) : \DateTimeImmutable
+ {
+ // @todo: only delivers/invoice/production (no offers ...)
+ $query = new Builder(self::$db);
+ $result = $query->select('billing_bill_performance_date')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_client', '=', $id)
+ ->orderBy('billing_bill_id', 'DESC')
+ ->limit(1)
+ ->execute()
+ ->fetch();
+
+ return new \DateTimeImmutable($result[0]);
+ }
+
+ public static function getItemRetentionRate(int $id, \DateTime $start, \DateTime $end) : float
+ {
+ }
+
+ public static function getItemLivetimeValue(int $id, \DateTime $start, \DateTime $end) : Money
+ {
+ }
+
+ public static function getNewestItemInvoices(int $id, int $limit = 10) : 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);
+
+ 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 getNewestClientInvoices(int $id, int $limit = 10) : 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->where(self::$table . '_' . $depth . '.billing_bill_client', '=', $id)
+ ->limit($limit);
+
+ 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 getItemTopCustomers(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
+ {
+ $depth = 3;
+
+ $query ??= ClientMapper::getQuery(null, [], RelationType::ALL, $depth);
+ $query->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
+ ->leftJoin(self::$table, self::$table . '_' . $depth)
+ ->on(ClientMapper::getTable() . '_' . $depth . '.clientmgmt_client_id', '=', self::$table . '_' . $depth . '.billing_bill_client')
+ ->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)
+ ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '_' . $depth . '.billing_bill_performance_date', '<=', $end)
+ ->orderBy('net_sales', 'DESC')
+ ->limit($limit)
+ ->groupBy(ClientMapper::getTable() . '_' . $depth . '.clientmgmt_client_id');
+
+ $clients = ClientMapper::getAllByQuery($query, RelationType::ALL, $depth);
+ $data = ClientMapper::getDataLastQuery();
+
+ return [$clients, $data];
+ }
+
+ public static function getItemRegionSales(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select(CountryMapper::getTable() . '.country_region')
+ ->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->leftJoin(CountryMapper::getTable())
+ ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy(CountryMapper::getTable() . '.country_region')
+ ->execute()
+ ->fetchAll(\PDO::FETCH_KEY_PAIR);
+
+ return $result;
+ }
+
+ public static function getItemCountrySales(int $id, \DateTime $start, \DateTime $end, int $limit = 10) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->select(CountryMapper::getTable() . '.country_code2')
+ ->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->leftJoin(CountryMapper::getTable())
+ ->on(self::$table . '.billing_bill_billCountry', '=', CountryMapper::getTable() . '.country_code2')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy(CountryMapper::getTable() . '.country_code2')
+ ->orderBy('net_sales', 'DESC')
+ ->limit($limit)
+ ->execute()
+ ->fetchAll(\PDO::FETCH_KEY_PAIR);
+
+ return $result;
+ }
+
+ public static function getItemMonthlySalesCosts(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->selectAs('SUM(billing_bill_element_total_salesprice_net)', 'net_sales')
+ ->selectAs('SUM(billing_bill_element_total_purchaseprice_net)', 'net_costs')
+ ->selectAs('YEAR(billing_bill_performance_date)', 'year')
+ ->selectAs('MONTH(billing_bill_performance_date)', 'month')
+ ->from(self::$table)
+ ->leftJoin(BillElementMapper::getTable())
+ ->on(self::$table . '.billing_bill_id', '=', BillElementMapper::getTable() . '.billing_bill_element_bill')
+ ->where(BillElementMapper::getTable() . '.billing_bill_element_item', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy('year', 'month')
+ ->orderBy(['year', 'month'], ['ASC', 'ASC'])
+ ->execute()
+ ->fetchAll();
+
+ return $result;
+ }
+
+ public static function getClientMonthlySalesCosts(int $id, \DateTime $start, \DateTime $end) : array
+ {
+ $query = new Builder(self::$db);
+ $result = $query->selectAs('SUM(billing_bill_net)', 'net_sales')
+ ->selectAs('SUM(billing_bill_costs)', 'net_costs')
+ ->selectAs('YEAR(billing_bill_performance_date)', 'year')
+ ->selectAs('MONTH(billing_bill_performance_date)', 'month')
+ ->from(self::$table)
+ ->where(self::$table . '.billing_bill_client', '=', $id)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '>=', $start)
+ ->andWhere(self::$table . '.billing_bill_performance_date', '<=', $end)
+ ->groupBy('year', 'month')
+ ->orderBy(['year', 'month'], ['ASC', 'ASC'])
+ ->execute()
+ ->fetchAll();
+
+ return $result;
+ }
+}
diff --git a/Theme/Backend/invoice-archive.tpl.php b/Theme/Backend/invoice-archive.tpl.php
deleted file mode 100755
index c268f29..0000000
--- a/Theme/Backend/invoice-archive.tpl.php
+++ /dev/null
@@ -1,18 +0,0 @@
-getData('nav')->render();
diff --git a/Theme/Backend/purchase-bill-list.tpl.php b/Theme/Backend/purchase-bill-list.tpl.php
new file mode 100755
index 0000000..133f267
--- /dev/null
+++ b/Theme/Backend/purchase-bill-list.tpl.php
@@ -0,0 +1,65 @@
+getData('bills') ?? [];
+
+echo $this->getData('nav')->render(); ?>
+
+
+
+
+
= $this->getHtml('Bills'); ?>
+
+
+
+
diff --git a/Theme/Backend/purchase-bill.tpl.php b/Theme/Backend/purchase-bill.tpl.php
new file mode 100755
index 0000000..a45783f
--- /dev/null
+++ b/Theme/Backend/purchase-bill.tpl.php
@@ -0,0 +1,294 @@
+getData('bill');
+$elements = $bill->getElements();
+
+$billPdf = $bill->getMediaByType('bill');
+
+echo $this->getData('nav')->render(); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = $this->getHtml('Invoice'); ?>
+
+
+
+
+
+
+ = $this->getHtml('Delivery'); ?>
+
+
+
+
+
+
+
+
+
+
+
= $this->getHtml('Invoice'); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = $this->getHtml('Payment'); ?>
+
+
+
+
+
+
+
+
+
+
+ = $this->getHtml('Media'); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ = $this->getHtml('Logs'); ?>
+
+
+ | IP
+ | = $this->getHtml('ID', '0', '0'); ?>
+ | = $this->getHtml('Name'); ?>
+ | = $this->getHtml('Log'); ?>
+ | = $this->getHtml('Date'); ?>
+ |
+
+ |
+ |
+
+ | = $this->printHtml($this->request->getOrigin()); ?>
+ | = $this->printHtml((string) $this->request->header->account); ?>
+ | = $this->printHtml((string) $this->request->header->account); ?>
+ | Create Invoice
+ | = $this->printHtml((new \DateTime('now'))->format('Y-m-d H:i:s')); ?>
+ |
+
+
+
+
+
+
+
diff --git a/Theme/Backend/purchase-invoice-list.tpl.php b/Theme/Backend/purchase-invoice-list.tpl.php
deleted file mode 100755
index 7b6ad25..0000000
--- a/Theme/Backend/purchase-invoice-list.tpl.php
+++ /dev/null
@@ -1,49 +0,0 @@
-l11nManager, $this->request, $this->response);
-$footerView->setTemplate('/Web/Templates/Lists/Footer/PaginationBig');
-$footerView->setPages(20);
-$footerView->setPage(1);
-
-echo $this->getData('nav')->render(); ?>
-
-
-
-
-
- = $this->getHtml('Invoices'); ?>
-
-
- | = $this->getHtml('ID', '0', '0'); ?>
- | = $this->getHtml('Type'); ?>
- | = $this->getHtml('SupplierID'); ?>
- | = $this->getHtml('Supplier'); ?>
- | = $this->getHtml('Net'); ?>
- | = $this->getHtml('Gross'); ?>
- | = $this->getHtml('Created'); ?>
- | = $this->getHtml('Due'); ?>
- |
-
- |
- |
- $value) : ++$count; ?>
-
-
- | = $this->getHtml('Empty', '0', '0'); ?>
-
- |
-
-
-
diff --git a/Theme/Backend/sales-bill-list.tpl.php b/Theme/Backend/sales-bill-list.tpl.php
index 7e3f8f3..4c410c7 100755
--- a/Theme/Backend/sales-bill-list.tpl.php
+++ b/Theme/Backend/sales-bill-list.tpl.php
@@ -21,7 +21,7 @@ echo $this->getData('nav')->render(); ?>
-
= $this->getHtml('Invoices'); ?>
+
= $this->getHtml('Bills'); ?>
@@ -40,7 +40,7 @@ echo $this->getData('nav')->render(); ?>
$value) :
++$count;
- $url = UriFactory::build('{/prefix}sales/invoice?{?}&id=' . $value->getId());
+ $url = UriFactory::build('{/prefix}sales/bill?{?}&id=' . $value->getId());
?>
| = $value->getNumber(); ?>
@@ -63,4 +63,3 @@ echo $this->getData('nav')->render(); ?>
-
|