mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-27 07:00:29 +01:00
934 lines
31 KiB
PHP
934 lines
31 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Xentral\Modules\CopperSurcharge\Service;
|
|
|
|
use DateTimeImmutable;
|
|
use DateTimeInterface;
|
|
use Xentral\Modules\CopperSurcharge\Data\CopperSurchargeData;
|
|
use Xentral\Modules\CopperSurcharge\Data\DocumentPositionData;
|
|
use Xentral\Modules\CopperSurcharge\Exception\InvalidDateFormatException;
|
|
use Xentral\Modules\CopperSurcharge\Wrapper\DocumentPositionWrapper;
|
|
use Xentral\Modules\CopperSurcharge\Wrapper\DocumentPositionWrapperInterface;
|
|
|
|
final class CopperSurchargeCalculator
|
|
{
|
|
/** @var RawMaterialGateway $rawMaterialGateway */
|
|
private $rawMaterialGateway;
|
|
|
|
/** @var PurchasePriceGateway $purchasePriceGateway */
|
|
private $purchasePriceGateway;
|
|
|
|
/** @var DocumentPositionWrapper $documentPositionWrapper */
|
|
private $documentPositionWrapper;
|
|
|
|
/** @var CopperSurchargeData $config */
|
|
private $config;
|
|
|
|
/** @var DocumentService $documentService */
|
|
private $documentService;
|
|
|
|
/** @var DocumentGateway $documentGateway */
|
|
private $documentGateway;
|
|
|
|
/**
|
|
* @param PurchasePriceGateway $purchasePriceGateway
|
|
* @param RawMaterialGateway $rawMaterialGateway
|
|
* @param DocumentPositionWrapperInterface $documentPositionWrapper
|
|
* @param DocumentService $documentService
|
|
* @param DocumentGateway $documentGateway
|
|
* @param CopperSurchargeData $copperSurchargeConfig
|
|
*/
|
|
public function __construct(
|
|
PurchasePriceGateway $purchasePriceGateway,
|
|
RawMaterialGateway $rawMaterialGateway,
|
|
DocumentPositionWrapperInterface $documentPositionWrapper,
|
|
DocumentService $documentService,
|
|
DocumentGateway $documentGateway,
|
|
CopperSurchargeData $copperSurchargeConfig
|
|
) {
|
|
$this->purchasePriceGateway = $purchasePriceGateway;
|
|
$this->rawMaterialGateway = $rawMaterialGateway;
|
|
$this->documentPositionWrapper = $documentPositionWrapper;
|
|
$this->documentService = $documentService;
|
|
$this->config = $copperSurchargeConfig;
|
|
$this->documentGateway = $documentGateway;
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
* @param array|DocumentPositionData[] $possibleCopperPositions
|
|
* @param array $copperPositionsInPartsList
|
|
*
|
|
* @return int
|
|
*/
|
|
public function handleCopperSurchargePositions(
|
|
string $docType,
|
|
int $docId,
|
|
array $possibleCopperPositions,
|
|
array $copperPositionsInPartsList
|
|
): int {
|
|
$calcDate = $this->evaluateCalcDate($docType, $docId);
|
|
|
|
if ($this->config->getSurchargePositionType() === CopperSurchargeData::POSITION_TYPE_ALWAYS) {
|
|
$this->createManyPositions(
|
|
$docType,
|
|
$docId,
|
|
$possibleCopperPositions,
|
|
$copperPositionsInPartsList,
|
|
$calcDate
|
|
);
|
|
|
|
return 0;
|
|
} elseif ($this->config->getSurchargePositionType() === CopperSurchargeData::POSITION_TYPE_ONETIME) {
|
|
$this->createSinglePosition(
|
|
$docType,
|
|
$docId,
|
|
$possibleCopperPositions,
|
|
$copperPositionsInPartsList,
|
|
$calcDate
|
|
);
|
|
|
|
return 1;
|
|
} else {
|
|
$this->createGroupPositions($docType, $docId, $copperPositionsInPartsList, $calcDate);
|
|
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Because there is no connection between positions,
|
|
* all surcharge positions get deleted and recreated in the next step
|
|
*
|
|
* @param string $docType
|
|
* @param int $docId
|
|
*/
|
|
public function resetDocument(string $docType, int $docId): void
|
|
{
|
|
$this->resetBetweenPositions($docId, $docType, $this->config->getCopperSurchargeArticleId());
|
|
$this->documentService->deleteCopperSurchargePositions(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
$this->documentService->updatePositionSorts($docType, $docId);
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
* @param array|DocumentPositionData[] $copperPositions
|
|
* @param array $copperPositionsInPartsList
|
|
* @param DateTimeInterface $calcDate
|
|
*
|
|
*/
|
|
private function createManyPositions(
|
|
string $docType,
|
|
int $docId,
|
|
array $copperPositions,
|
|
array $copperPositionsInPartsList,
|
|
DateTimeInterface $calcDate
|
|
): void {
|
|
foreach ($copperPositions as $position) {
|
|
$amount = $this->calcAmount($docType, $position->getPositionId(), $position->getArticleId());
|
|
$copperBase = $this->getCopperBase($position->getArticleId());
|
|
|
|
$price = $this->calculateCopperSurchargePrice(
|
|
$copperBase,
|
|
$amount,
|
|
$calcDate
|
|
);
|
|
|
|
$newPosId = $this->addCopperSurchargePosition(
|
|
$docType,
|
|
$docId,
|
|
$price,
|
|
$amount,
|
|
$copperBase,
|
|
$position->getCurrency(),
|
|
$calcDate
|
|
);
|
|
|
|
$this->documentService->updatePositionSort($docType, $docId, $position->getPositionId(), $newPosId);
|
|
}
|
|
|
|
if (empty($copperPositionsInPartsList)) {
|
|
return;
|
|
}
|
|
foreach ($copperPositionsInPartsList as $partListPosition) {
|
|
$partListData = $this->evaluateSurchargeDataForPartList(
|
|
$partListPosition['article_id'],
|
|
$partListPosition['pos_id'],
|
|
$calcDate,
|
|
$docType,
|
|
$partListPosition['amount']
|
|
);
|
|
|
|
$newPosId = $this->addCopperSurchargePosition(
|
|
$docType,
|
|
$docId,
|
|
$partListData['price'],
|
|
$partListData['amount'],
|
|
$partListData['copper_base'],
|
|
$partListPosition['currency'],
|
|
$calcDate
|
|
);
|
|
|
|
$this->documentService->updatePositionSort($docType, $docId, $partListData['position_id'], $newPosId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $partListHeadId
|
|
* @param int $positionId
|
|
* @param DateTimeInterface $calcDate
|
|
* @param string $docType
|
|
* @param float $partListPositionAmount
|
|
*
|
|
* @return array
|
|
*/
|
|
private function evaluateSurchargeDataForPartList(
|
|
int $partListHeadId,
|
|
int $positionId,
|
|
DateTimeInterface $calcDate,
|
|
string $docType,
|
|
float $partListPositionAmount
|
|
): array {
|
|
$copperArticles =
|
|
$this->getCopperArticlesFromPartList(
|
|
$partListHeadId,
|
|
$this->config->getSurchargeMaintenanceType(),
|
|
$this->config->getCopperNumberOption(),
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
$amount = 0;
|
|
$price = 0.0;
|
|
$copperBase = 0.0;
|
|
|
|
foreach ($copperArticles as $copperArticle) {
|
|
$amount += $copperArticle['amount'];
|
|
$copperBase = $this->getCopperBase($copperArticle['article_id']);
|
|
|
|
$price += $this->calculateCopperSurchargePrice(
|
|
$copperBase,
|
|
$amount,
|
|
$calcDate
|
|
);
|
|
}
|
|
|
|
return [
|
|
'amount' => $amount * $partListPositionAmount,
|
|
'price' => $price * $partListPositionAmount,
|
|
'copper_base' => $copperBase,
|
|
'position_id' => $this->documentGateway->evaluatePartListLastPositionId($docType, $positionId),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
* @param float $price
|
|
* @param float $amount
|
|
* @param float $copperBase
|
|
* @param $currency
|
|
* @param DateTimeInterface $calcDate
|
|
*
|
|
* @return int
|
|
*/
|
|
private function addCopperSurchargePosition(
|
|
string $docType,
|
|
int $docId,
|
|
float $price,
|
|
float $amount,
|
|
float $copperBase,
|
|
$currency,
|
|
DateTimeInterface $calcDate
|
|
): int {
|
|
$copperSurchargeArticleId = $this->config->getCopperSurchargeArticleId();
|
|
$articleData = $this->documentGateway->getArticleData($copperSurchargeArticleId);
|
|
$description = $this->findCopperSurchargeArticleDescription(
|
|
$amount,
|
|
$copperBase,
|
|
$price,
|
|
$articleData,
|
|
$calcDate
|
|
);
|
|
|
|
return $this->documentPositionWrapper->addPositionManuallyWithPrice(
|
|
$docType,
|
|
$docId,
|
|
$copperSurchargeArticleId,
|
|
$articleData,
|
|
1,
|
|
$price,
|
|
$currency,
|
|
$description
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param float $amount
|
|
* @param float $copperBase
|
|
* @param float $price
|
|
* @param array $articleData
|
|
* @param DateTimeInterface $calcDate
|
|
*
|
|
* @return string
|
|
*/
|
|
private function findCopperSurchargeArticleDescription(
|
|
float $amount,
|
|
float $copperBase,
|
|
float $price,
|
|
array $articleData,
|
|
DateTimeInterface $calcDate
|
|
): string {
|
|
$description = $articleData['description'];
|
|
|
|
$delPrice = $this->purchasePriceGateway->getDelCopperPriceByDate(
|
|
$calcDate,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
|
|
$price = number_format($price, 2, ",", ".");
|
|
$delPrice = number_format($delPrice, 2, ",", ".");
|
|
$copperBase = number_format($copperBase, 2, ",", ".");
|
|
$amount = str_replace('.', ',', $amount);
|
|
|
|
$description = str_replace('{NETPRICE}', $price, $description);
|
|
$description = str_replace('{ARTIKELNUMMER}', $articleData['number'], $description);
|
|
$description = str_replace('{ARTIKELNAME}', $articleData['name_de'], $description);
|
|
$description = str_replace('{COPPERBASIS}', $copperBase, $description);
|
|
$description = str_replace('{COPPERNUMBER}', $amount, $description);
|
|
$description = str_replace('{DELVALUE}', $delPrice, $description);
|
|
|
|
return $description;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
* @param array|DocumentPositionData[] $copperPositions
|
|
* @param array $copperPositionsInPartsList
|
|
* @param DateTimeInterface $calcDate
|
|
*
|
|
* @return int
|
|
*/
|
|
private function createSinglePosition(
|
|
string $docType,
|
|
int $docId,
|
|
array $copperPositions,
|
|
array $copperPositionsInPartsList,
|
|
DateTimeInterface $calcDate
|
|
): int {
|
|
$price = 0.0;
|
|
$totalAmount = 0.0;
|
|
$currency = 'EUR';
|
|
$copperBase = 0.0;
|
|
foreach ($copperPositions as $position) {
|
|
$currency = $position->getCurrency();
|
|
$amount = $this->calcAmount($docType, $position->getPositionId(), $position->getArticleId());
|
|
$totalAmount += $amount;
|
|
$copperBase = $this->getCopperBase($position->getArticleId());
|
|
$price += $this->calculateCopperSurchargePrice(
|
|
$copperBase,
|
|
$amount,
|
|
$calcDate
|
|
);
|
|
}
|
|
|
|
if (!empty($copperPositionsInPartsList)) {
|
|
foreach ($copperPositionsInPartsList as $position) {
|
|
$partListData = $this->evaluateSurchargeDataForPartList(
|
|
$position['article_id'],
|
|
$position['pos_id'],
|
|
$calcDate,
|
|
$docType,
|
|
$position['amount']
|
|
);
|
|
|
|
$totalAmount += $partListData['amount'];
|
|
$price += $partListData['price'];
|
|
$copperBase = $partListData['copper_base'];
|
|
}
|
|
}
|
|
|
|
$newPosId = 0;
|
|
if ($price > 0) {
|
|
$newPosId = $this->addCopperSurchargePosition(
|
|
$docType,
|
|
$docId,
|
|
$price,
|
|
$totalAmount,
|
|
$copperBase,
|
|
$currency,
|
|
$calcDate
|
|
);
|
|
}
|
|
|
|
return $newPosId;
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
* @param array $copperPositionsInPartsList
|
|
* @param DateTimeInterface $calcDate
|
|
*/
|
|
private function createGroupPositions(
|
|
string $docType,
|
|
int $docId,
|
|
array $copperPositionsInPartsList,
|
|
DateTimeInterface $calcDate
|
|
): void {
|
|
if ($this->config->getSurchargeMaintenanceType() === CopperSurchargeData::SURCHARGE_MAINTENANCE_TYPE_APP) {
|
|
$positions = $this->rawMaterialGateway->findAllPositionsForGrouped(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
} else {
|
|
$positions = $this->documentGateway->findAllPositionsForGrouped(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperNumberOption()
|
|
);
|
|
}
|
|
|
|
$price = 0.0;
|
|
$totalAmount = 0.0;
|
|
$currency = 'EUR';
|
|
$prev = null;
|
|
$copperBase = 0.0;
|
|
$lastSort = 0;
|
|
|
|
foreach ($positions as $key => $position) {
|
|
if ((bool)$position['is_copper']) {
|
|
$amount = $this->calcAmount($docType, (int)$position['pos_id'], (int)$position['article_id']);
|
|
$copperBase = $this->getCopperBase($position['article_id']);
|
|
$price += $this->calculateCopperSurchargePrice(
|
|
$copperBase,
|
|
$amount,
|
|
$calcDate
|
|
);
|
|
$currency = $position['currency'];
|
|
$totalAmount += $amount;
|
|
}
|
|
|
|
if ($position['between_type'] === 'gruppe') {
|
|
if (!empty($copperPositionsInPartsList)) {
|
|
$partListElements = $this->getElementsFromPartListBetweenSorts(
|
|
$copperPositionsInPartsList,
|
|
$lastSort,
|
|
$position['sort']
|
|
);
|
|
|
|
foreach ($partListElements as $partListElement) {
|
|
$partListKey = $partListElement['part_list_key'];
|
|
$partListData = $this->evaluateSurchargeDataForPartList(
|
|
$partListElement['article_id'],
|
|
$position['pos_id'],
|
|
$calcDate,
|
|
$docType,
|
|
$partListElement['amount']
|
|
);
|
|
$totalAmount += $partListData['amount'];
|
|
$price += $partListData['price'];
|
|
$copperBase = $partListData['copper_base'];
|
|
unset($copperPositionsInPartsList[$partListKey]);
|
|
}
|
|
}
|
|
if ($price > 0.0) {
|
|
$newPosId = $this->addCopperSurchargePosition(
|
|
$docType,
|
|
$docId,
|
|
$price,
|
|
$totalAmount,
|
|
$copperBase,
|
|
$currency,
|
|
$calcDate
|
|
);
|
|
if (!empty($prev)) {
|
|
$this->documentService->updatePositionSort($docType, $docId, (int)$prev['pos_id'], $newPosId);
|
|
}
|
|
$price = 0.0;
|
|
$totalAmount = 0.0;
|
|
$lastSort = $position['sort'];
|
|
}
|
|
}
|
|
|
|
$prev = $position;
|
|
}
|
|
|
|
if (!empty($copperPositionsInPartsList)) {
|
|
foreach ($copperPositionsInPartsList as $partListElement) {
|
|
$partListData = $this->evaluateSurchargeDataForPartList(
|
|
$partListElement['article_id'],
|
|
$partListElement['pos_id'],
|
|
$calcDate,
|
|
$docType,
|
|
$partListElement['amount']
|
|
);
|
|
$totalAmount += $partListData['amount'];
|
|
$price += $partListData['price'];
|
|
$copperBase = $partListData['copper_base'];
|
|
}
|
|
}
|
|
if ($price > 0.0) {
|
|
$this->addCopperSurchargePosition(
|
|
$docType,
|
|
$docId,
|
|
$price,
|
|
$totalAmount,
|
|
$copperBase,
|
|
$currency,
|
|
$calcDate
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param float $copperBase
|
|
* @param float $amount
|
|
* @param DateTimeInterface $calcDate
|
|
*
|
|
* @return float
|
|
*/
|
|
private function calculateCopperSurchargePrice(
|
|
float $copperBase,
|
|
float $amount,
|
|
DateTimeInterface $calcDate
|
|
): float {
|
|
$delPrice = $this->purchasePriceGateway->getDelCopperPriceByDate(
|
|
$calcDate,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
$perCent = $this->config->getSurchargeDeliveryCosts() / 100;
|
|
|
|
return (($delPrice + ($delPrice * $perCent)) - $copperBase) * $amount / 100;
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $positionId
|
|
* @param int $positionArticleId
|
|
*
|
|
* @return float
|
|
*/
|
|
private function calcAmount(string $docType, int $positionId, int $positionArticleId): float
|
|
{
|
|
if ($this->config->getSurchargeMaintenanceType() === CopperSurchargeData::SURCHARGE_MAINTENANCE_TYPE_APP) {
|
|
$amount = $this->rawMaterialGateway->getRawMaterialAmount(
|
|
$positionArticleId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
} else {
|
|
$articleId = $this->documentGateway->getArticleIdByPositionId($docType, $positionId);
|
|
$amount = $this->documentGateway->getArticleCopperNumber(
|
|
$articleId,
|
|
$this->config->getCopperNumberOption()
|
|
);
|
|
}
|
|
|
|
$documentAmount = $this->documentGateway->getPositionAmount($docType, $positionId);
|
|
|
|
$amount *= $documentAmount;
|
|
|
|
return (float)$amount;
|
|
}
|
|
|
|
/**
|
|
* @param int $positionArticleId
|
|
*
|
|
* @return float
|
|
*/
|
|
private function getCopperBase(int $positionArticleId): float
|
|
{
|
|
$copperBase = $this->config->getSurchargeCopperBaseStandard();
|
|
|
|
$articleCopperBaseField = $this->config->getSurchargeCopperBase();
|
|
if (!empty($articleCopperBaseField)) {
|
|
$copperBaseTemp = $this->documentGateway->getArticleCopperBase($positionArticleId, $articleCopperBaseField);
|
|
if (!empty($copperBaseTemp)) {
|
|
$copperBase = $copperBaseTemp;
|
|
}
|
|
}
|
|
|
|
return $copperBase;
|
|
}
|
|
|
|
/**
|
|
* @param string $doctype
|
|
* @param int $docId
|
|
*
|
|
* @throws InvalidDateFormatException
|
|
* @return DateTimeInterface
|
|
*/
|
|
private function evaluateCalcDate(string $doctype, int $docId): DateTimeInterface
|
|
{
|
|
$orderOfferId = 0;
|
|
if ($doctype === 'auftrag') {
|
|
$orderOfferId = $this->documentGateway->findOrderOfferId($docId);
|
|
}
|
|
|
|
if (
|
|
$doctype === 'rechnung' &&
|
|
$this->config->getSurchargeInvoice() === CopperSurchargeData::INVOICE_CREATE_POS_BY_DELIVERY_DATE
|
|
) {
|
|
$calcDate = $this->documentGateway->findDeliveryDate($docId);
|
|
if (empty($calcDate)) {
|
|
$calcDate = new DateTimeImmutable();
|
|
}
|
|
} elseif (
|
|
$doctype === 'rechnung' &&
|
|
$this->config->getSurchargeInvoice() === CopperSurchargeData::INVOICE_CREATE_POS_BY_ORDER_DATE
|
|
) {
|
|
$orderId = $this->documentGateway->findInvoiceOrderId($docId);
|
|
if (empty($orderId)) {
|
|
$calcDate = new DateTimeImmutable();
|
|
} else {
|
|
$calcDate = $this->documentGateway->getCalcDate('auftrag', $orderId);
|
|
}
|
|
} elseif ($doctype === 'rechnung' &&
|
|
$this->config->getSurchargeInvoice() === CopperSurchargeData::INVOICE_CREATE_POS_BY_INVOICE_DATE) {
|
|
$calcDate = $this->documentGateway->getCalcDate($doctype, $docId);
|
|
} elseif ($doctype === 'rechnung' &&
|
|
$this->config->getSurchargeInvoice() === CopperSurchargeData::INVOICE_CREATE_POS_BY_OFFER_DATE) {
|
|
$offerId = $this->documentGateway->findInvoiceOfferId($docId);
|
|
if (!empty($offerId)) {
|
|
$calcDate = $this->documentGateway->getCalcDate('angebot', $offerId);
|
|
} else {
|
|
$calcDate = new DateTimeImmutable();
|
|
}
|
|
} elseif (
|
|
$doctype === 'auftrag' &&
|
|
$orderOfferId !== 0 &&
|
|
$this->config->getSurchargeDocumentConversion() === CopperSurchargeData::DOCUMENT_CONVERSION_FROM_OFFER
|
|
) {
|
|
$calcDate = $this->documentGateway->getCalcDate('angebot', $orderOfferId);
|
|
} else {
|
|
$calcDate = new DateTimeImmutable();
|
|
}
|
|
|
|
return $calcDate;
|
|
}
|
|
|
|
/**
|
|
* @param int $docId
|
|
* @param string $docType
|
|
* @param int $copperSurchargeArticleId
|
|
*/
|
|
private function resetBetweenPositions(int $docId, string $docType, int $copperSurchargeArticleId): void
|
|
{
|
|
if ($this->config->getSurchargeMaintenanceType() === CopperSurchargeData::SURCHARGE_MAINTENANCE_TYPE_APP) {
|
|
$positions = $this->rawMaterialGateway->findAllPositionsForGrouped(
|
|
$docType,
|
|
$docId,
|
|
$copperSurchargeArticleId
|
|
);
|
|
} else {
|
|
$positions = $this->documentGateway->findAllPositionsForGrouped(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperNumberOption()
|
|
);
|
|
}
|
|
|
|
$offset = 0;
|
|
foreach ($positions as $position) {
|
|
if ((int)$position['article_id'] === $copperSurchargeArticleId) {
|
|
$offset--;
|
|
}
|
|
|
|
if ((int)$position['pos_type'] === 2 && $offset < 0) {
|
|
$this->documentService->updateBetweenSort(
|
|
(int)$position['between_id'],
|
|
(int)$position['sort'] + $offset
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docId
|
|
*/
|
|
public function deleteRemainingCopperSurchargeArticles(string $docType, int $docId): void
|
|
{
|
|
if ($this->config->getSurchargeMaintenanceType() === CopperSurchargeData::SURCHARGE_MAINTENANCE_TYPE_ARTICLE) {
|
|
$hasCopperArticles =
|
|
$this->documentGateway->hasCopperArticles(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperNumberOption()
|
|
);
|
|
} else {
|
|
$hasCopperArticles =
|
|
$this->rawMaterialGateway->hasCopperArticles(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
}
|
|
|
|
if (!$hasCopperArticles) {
|
|
$this->documentService->deleteCopperSurchargePositions(
|
|
$docType,
|
|
$docId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $posId
|
|
*/
|
|
public function updatePositionContributionMargin(string $docType, int $posId)
|
|
{
|
|
$this->documentService->updatePositionContributionMargin($docType, $posId, 0);
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $posId
|
|
*/
|
|
public function updatePositionPurchasePrice(string $docType, int $posId)
|
|
{
|
|
$this->documentService->updatePositionPurchasePrice($docType, $posId, 0.0);
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
*
|
|
* @param int $docTypeId
|
|
*
|
|
* @return array|DocumentPositionData[]
|
|
*/
|
|
public function findPositionsForMaintenanceApp(string $docType, int $docTypeId): array
|
|
{
|
|
$data = $this->rawMaterialGateway->findPositions(
|
|
$docType,
|
|
$docTypeId,
|
|
$this->config->getCopperSurchargeArticleId()
|
|
);
|
|
|
|
return $this->transformToDocumentPositionData($data);
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
*
|
|
* @param int $docTypeId
|
|
*
|
|
* @return array|DocumentPositionData[]
|
|
*/
|
|
public function findPositionsForMaintenanceArticle(string $docType, int $docTypeId): array
|
|
{
|
|
$data = $this->documentGateway->findPositions(
|
|
$docType,
|
|
$docTypeId,
|
|
$this->config->getCopperNumberOption()
|
|
);
|
|
|
|
return $this->transformToDocumentPositionData($data);
|
|
}
|
|
|
|
/**
|
|
* @param array $copperPositionsRaw
|
|
*
|
|
* @return array|DocumentPositionData[]
|
|
*/
|
|
private function transformToDocumentPositionData(array $copperPositionsRaw): array
|
|
{
|
|
$documentPositions = [];
|
|
foreach ($copperPositionsRaw as $position) {
|
|
$data = new DocumentPositionData(
|
|
(int)$position['pos_id'],
|
|
(int)$position['article_id'],
|
|
(string)$position['currency']
|
|
);
|
|
$documentPositions[] = $data;
|
|
}
|
|
|
|
return $documentPositions;
|
|
}
|
|
|
|
/**
|
|
* @param int $doctypeId
|
|
* @param string $doctype
|
|
*/
|
|
public function updateCopperSurchargeArticles(int $doctypeId, string $doctype)
|
|
{
|
|
$copperSurchargeArticleId = $this->config->getCopperSurchargeArticleId();
|
|
$surchargePositions = $this->documentGateway->findCopperSurchargeArticlePositionIds(
|
|
$doctype,
|
|
$doctypeId,
|
|
$copperSurchargeArticleId
|
|
);
|
|
|
|
if (!empty($surchargePositions)) {
|
|
foreach ($surchargePositions as $surchargePosition) {
|
|
$this->updatePositionContributionMargin($doctype, (int)$surchargePosition['pos_id']);
|
|
$this->updatePositionPurchasePrice($doctype, (int)$surchargePosition['pos_id']);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $copperPositionsInPartsList
|
|
* @param int $lastSort
|
|
* @param int $nextSort
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getElementsFromPartListBetweenSorts(
|
|
array $copperPositionsInPartsList,
|
|
int $lastSort,
|
|
int $nextSort
|
|
): array {
|
|
$result = [];
|
|
foreach ($copperPositionsInPartsList as $partListKey => $position) {
|
|
$currentSort = $position['sort'];
|
|
if ($currentSort > $lastSort && $currentSort <= $nextSort) {
|
|
$position['part_list_key'] = $partListKey;
|
|
$result[] = $position;
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param int $partListHeadId
|
|
* @param int $surchargeMaintenanceType
|
|
* @param string $copperNumberOption
|
|
* @param int $copperArticleId
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getCopperArticlesFromPartList(
|
|
int $partListHeadId,
|
|
int $surchargeMaintenanceType,
|
|
string $copperNumberOption,
|
|
int $copperArticleId
|
|
): array {
|
|
$result = [];
|
|
$childElements = $this->documentGateway->getAllPartListChildElements($partListHeadId);
|
|
|
|
foreach ($childElements as $childElement) {
|
|
if ($surchargeMaintenanceType === CopperSurchargeData::SURCHARGE_MAINTENANCE_TYPE_ARTICLE) {
|
|
$possibleArticle = $this->documentGateway->findPossibleCopperArticle(
|
|
$childElement['id'],
|
|
$copperNumberOption
|
|
);
|
|
} else {
|
|
$possibleArticle = $this->rawMaterialGateway->findPossibleCopperArticle(
|
|
$childElement['id'],
|
|
$copperArticleId
|
|
);
|
|
}
|
|
|
|
if (empty($possibleArticle)) {
|
|
continue;
|
|
}
|
|
|
|
$result[] = [
|
|
'article_id' => $possibleArticle['article_id'],
|
|
'amount' => $possibleArticle['amount'] * $childElement['amount'],
|
|
];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docTypeId
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findPositionsForMaintenanceAppInPartsList(
|
|
string $docType,
|
|
int $docTypeId
|
|
): array {
|
|
$result = [];
|
|
|
|
$copperArticleId = $this->config->getCopperSurchargeArticleId();
|
|
|
|
$headArticles = $this->documentGateway->findPartListHeadArticles($docType, $docTypeId);
|
|
|
|
foreach ($headArticles as $headArticle) {
|
|
$childElements = $this->documentGateway->getAllPartListChildElements($headArticle['id']);
|
|
$hasCopper = false;
|
|
foreach ($childElements as $childElement) {
|
|
if (!$hasCopper) {
|
|
$hasCopper = !empty(
|
|
$this->rawMaterialGateway->findPossibleCopperArticle(
|
|
$childElement['id'],
|
|
$copperArticleId
|
|
)
|
|
);
|
|
}
|
|
}
|
|
if ($hasCopper) {
|
|
$result[] = [
|
|
'article_id' => $headArticle['id'],
|
|
'sort' => $headArticle['sort'],
|
|
'pos_id' => $headArticle['pos_id'],
|
|
'currency' => $headArticle['currency'],
|
|
'amount' => (float)$headArticle['amount'],
|
|
];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param string $docType
|
|
* @param int $docTypeId
|
|
*
|
|
* @return array
|
|
*/
|
|
public function findPositionsForMaintenanceArticleInPartsList(
|
|
string $docType,
|
|
int $docTypeId
|
|
): array {
|
|
$result = [];
|
|
|
|
$copperNumberOption = $this->config->getCopperNumberOption();
|
|
|
|
$headArticles = $this->documentGateway->findPartListHeadArticles($docType, $docTypeId);
|
|
|
|
foreach ($headArticles as $headArticle) {
|
|
$childElements = $this->documentGateway->getAllPartListChildElements((int)$headArticle['id']);
|
|
$hasCopper = false;
|
|
foreach ($childElements as $childElement) {
|
|
if (!$hasCopper) {
|
|
$hasCopper = !empty(
|
|
$this->documentGateway->findPossibleCopperArticle(
|
|
$childElement['id'],
|
|
$copperNumberOption
|
|
)
|
|
);
|
|
}
|
|
}
|
|
if ($hasCopper) {
|
|
$result[] = [
|
|
'article_id' => $headArticle['id'],
|
|
'sort' => $headArticle['sort'],
|
|
'pos_id' => $headArticle['pos_id'],
|
|
'currency' => $headArticle['currency'],
|
|
'amount' => (float)$headArticle['amount'],
|
|
];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|