thresholdNormal = $thresholdNormal; } /** * @param float $tax * * @return $this */ public function setTaxNormal(float $tax): self { $this->thresholdNormal = $tax; return $this; } /** * @param float $inclVat * * @return BusinessCase */ public function getEmployeeTipBusinessCase(float $inclVat): BusinessCase { return $this->getNotTaxableBusinessCase('TrinkgeldAN', $inclVat); } /** * @param string $type * @param float $inclVat * * @return BusinessCase */ public function getNotTaxableBusinessCase(string $type, float $inclVat): BusinessCase { return new BusinessCase( $type, AmountPerVatIdCollection::fromDbState( [ [ 'vat_definition_export_id' => self::VAT_DEFINITION_EXPORT_ID_NOT_TAXABLE, 'incl_vat' => $inclVat, 'excl_vat' => null, 'vat' => 0, ], ] ) ); } /** * @param float $inclVat * @param string $baseCurrencyCode * * @return CashPointClosingPaymentType */ public function getPaymentType(float $inclVat, string $baseCurrencyCode = 'EUR'): CashPointClosingPaymentType { return new CashPointClosingPaymentType('Bar', $inclVat, $baseCurrencyCode); } /** * @param array $posJournals * * @return AmountPerVatIdCollection */ public function createAmountPerVatIdCollectionFromPosJournalDbState( array $posJournals ): AmountPerVatIdCollection { $collection = new AmountPerVatIdCollection(); foreach ($posJournals as $posJournal) { $collection->addAmountPerVatId( $this->createAmountPerVatIdFromPosJournalDbState($posJournal) ); } return $collection->groupByVatDefinitionExportId(); } /** * @param array $posJournal * * @return AmountPerVatId */ public function createAmountPerVatIdFromPosJournalDbState( array $posJournal ): AmountPerVatId { if ($this->thresholdNormal === null) { throw new InvalidArgumentException('no normal tax set'); } $vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_NOT_TAXABLE; if ($posJournal['tax'] > $this->thresholdNormal) { $vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_NORMAL; } elseif ($posJournal['tax'] > 0) { $vatDefinitionExportId = self::VAT_DEFINITION_EXPORT_ID_REDUCED; } return new AmountPerVatId( $vatDefinitionExportId, (float)$posJournal['amount_gross'], (float)$posJournal['amount_net'] ); } /** * @param array $posJournals * * @return BusinessCaseCollection */ public function createBusinessCaseCollection( array $posJournals ): BusinessCaseCollection { $collection = new BusinessCaseCollection(); foreach ($posJournals as $posJournal) { $collection->addBusinessCase($this->createBusinessCase($posJournal)); } return $collection->groupByType(); } /** * @param TransactionReponse $transactionResponse * * @return AmountsPerPaymentTypeCollection */ public function getPaymentTypesFromTransaction(TransactionReponse $transactionResponse): AmountsPerPaymentTypeCollection { $instance = new AmountsPerPaymentTypeCollection(); $schema = $transactionResponse->getSchema(); if ($schema === null) { return $instance; } $standardV1 = $schema->getStandardV1(); if ($standardV1 === null) { return $instance; } $receipt = $standardV1->getReceipt(); if ($receipt === null) { return $instance; } return $receipt->getAmountsPerPaymentType(); } /** * @param TransactionReponseCollection $collection * * @return AmountsPerPaymentTypeCollection */ public function getPaymentTypesFromTransactionCollection(TransactionReponseCollection $collection ): AmountsPerPaymentTypeCollection { $instance = new AmountsPerPaymentTypeCollection(); /** @var TransactionReponse $item */ foreach ($collection as $item) { $instance->combine($this->getPaymentTypesFromTransaction($item)); } return $instance; } /** * @param AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection * * @return CashAmountByCurrencyCollection */ public function getCashAmountByCurrencyCollection( AmountsPerPaymentTypeCollection $amountsPerPaymentTypeCollection ): CashAmountByCurrencyCollection { $currencyCodes = $amountsPerPaymentTypeCollection->getCurrencyCodes(); $collection = new CashAmountByCurrencyCollection(); foreach ($currencyCodes as $currencyCode) { $collection->addAmountPerCurrecy( new CashAmountByCurrency($amountsPerPaymentTypeCollection->getSum($currencyCode), $currencyCode) ); } return $collection; } /** * @param array $posJournals * * @return CashPointClosingPaymentTypeCollection */ public function getCashPointClosingPaymentTypeCollection(array $posJournals ): CashPointClosingPaymentTypeCollection { $collection = new CashPointClosingPaymentTypeCollection(); foreach ($posJournals as $posJournal) { $collection->addPaymentType($this->getCashPointClosingPaymentType($posJournal)); } return $collection->getGrouped(); } /** * @param array $posJournalCollection * * @return CashPointClosingPaymentTypeCollection */ public function getCashPointClosingPaymentTypeCollectionByPosJournalCollection(array $posJournalCollection ): CashPointClosingPaymentTypeCollection { $collection = new CashPointClosingPaymentTypeCollection(); foreach ($posJournalCollection as $posJournals) { $collection->combine($this->getCashPointClosingPaymentTypeCollection($posJournals)); } return $collection->getGrouped(); } /** * @param array $posJournal * * @return CashPointClosingPaymentType */ public function getCashPointClosingPaymentType(array $posJournal): CashPointClosingPaymentType { $currencyCode = !empty($posJournal['currency']) ? $posJournal['currency'] : 'EUR'; $amount = (float)$posJournal['amount_gross']; switch ($posJournal['payment_type']) { case 'ec': case 'eckarte': $type = 'ECKarte'; break; case 'kredit': case 'kreditkarte': $type = 'Kreditkarte'; break; case 'Ueb': case 'rechnung': $type = 'Unbar'; break; default: $type = 'Bar'; break; } if ($amount == 0) { $type = 'Keine'; } return new CashPointClosingPaymentType($type, $amount, $currencyCode); } public function getCashPointClosingTransactionCollection( TransactionReponseCollection $transactionResponseCollection, array $posJournalCollection, array $posSessions ): CashPointClosingTransactionCollection { $collection = new CashPointClosingTransactionCollection(); /** @var TransactionReponse $item */ foreach ($transactionResponseCollection as $item) { $posJournals = $posJournalCollection[$item->getId()]; $posSession = $posSessions[$item->getId()]; $collection->addTransaction($this->getCashPointClosingTransaction($item, $posJournals, $posSession)); } return $collection; } /** * @param string $receiptType * * @return string */ public function mapReceiptType(string $receiptType): string { switch ($receiptType) { case 'RECEIPT': return 'Beleg'; case 'TRANSFER': return 'AVTransfer'; case 'ORDER': return 'AVBestellung'; case 'CANCELLATION': return 'AVBelegabbruch'; case 'ABORT': return 'AVBelegabbruch'; case 'BENEFIT_IN_KIND': return 'AVSachbezug'; case 'INVOICE': return 'AVRechnung'; case 'OTHER': return 'AVSonstige'; case 'ANNULATION': return 'AVBelegstorno'; default: return $receiptType; } } /** * @param TransactionReponse $transactionResponse * @param array $posJournals * @param array $posSession * * @return CashPointClosingTransaction */ public function getCashPointClosingTransaction( TransactionReponse $transactionResponse, array $posJournals, array $posSession ): CashPointClosingTransaction { $businessCollection = $this->createBusinessCaseCollection($posJournals); $user = new CashPointClosingTransactionUser((string)$posSession['kassiererId']); $isBuyerCustomer = !empty($posSession['address']['kundennummer']); $needUserAddress = !empty($posSession['soll']) && $posSession['soll'] >= self::BUYER_ADDRESS_THRESHOLD_AMOUNT; $userAddress = !$needUserAddress ? null : new CashPointClosingTransactionAddress( $posSession['address']['strasse'], $posSession['address']['plz'], $posSession['address']['ort'], $posSession['land_iso3'] ); $buyer = new CashPointClosingTransactionBuyer( $posSession['addr']['name'], $isBuyerCustomer ? $posSession['address']['kundennummer'] : $posSession['address']['mitarbeiternummer'], $isBuyerCustomer ? 'Kunde' : 'Mitarbeiter', $userAddress ); // TODO add error $schema = $transactionResponse->getSchema(); $standardV1 = $schema === null ? null : $schema->getStandardV1(); $receipt = $standardV1 === null ? null : $standardV1->getReceipt(); $receiptType = $receipt === null ? 'Beleg' : $this->mapReceiptType($receipt->getReceiptType()); $lines = new CashPointClosingTransactionLineCollection();//@todo lines generieren return new CashPointClosingTransaction( new TransactionHead( $transactionResponse->getId(), $transactionResponse->getId(), $transactionResponse->getClientId(), $receiptType, false, $transactionResponse->getNumber(), $transactionResponse->getTimeStart(), $transactionResponse->getTimeEnd(), $user, $buyer ), new TransactionData( $businessCollection->getSumInclVat(), $this->getCashPointClosingPaymentTypeCollection($posJournals), $this->createAmountPerVatIdCollectionFromPosJournalDbState($posJournals), $lines ), new TransactionSecurity($transactionResponse->getId()) ); } public static function getLines(BusinessCaseCollection $businessCollection ): CashPointClosingTransactionLineCollection { $lineItemExportId = ''; $lines = new CashPointClosingTransactionLineCollection(); /** @var BusinessCase $businessCase */ foreach ($businessCollection as $businessCase) { $line = new CashPointClosingTransactionLine($businessCase, $lineItemExportId, false); $lines->addLine($line); } return $lines; } /** * @param array $posJournal * * @return BusinessCase */ public function createBusinessCase(array $posJournal): BusinessCase { switch ($posJournal['type']) { case 'Anfangsbestand': $type = 'Anfangsbestand'; break; case 'Einlage': case 'Entnahme': $type = 'Geldtransit'; break; case 'RE_Beleg': case 'GS_Beleg': $type = 'Umsatz'; break; case 'Gutscheineinlösung': $type = 'MehrzweckgutscheinEinloesung'; break; case 'Gutscheinverkauf': $type = 'MehrzweckgutscheinKauf'; break; case 'Kassendifferenz': $type = 'DifferenzSollIst'; break; case 'Trinkgeld': $type = 'TrinkgeldAN'; break; default: $type = 'Umsatz'; break; } return new BusinessCase( $type, $this->createAmountPerVatIdCollectionFromPosJournalDbState([$posJournal]) ); } }