user(); $api_key = config('services.mindee.api_key'); if (!$api_key) throw new Exception('Mindee API key not configured'); $this->checkLimits(); // perform parsing $mindeeClient = new Client($api_key); $inputSource = $mindeeClient->sourceFromBytes($this->file->get(), $this->file->getClientOriginalName()); $result = $mindeeClient->parse(InvoiceV4::class, $inputSource); $this->incrementRequestCounts(); /** @var \Mindee\Product\Invoice\InvoiceV4Document $prediction */ $prediction = $result->document->inference->prediction; if ($prediction->documentType->value !== 'INVOICE') throw new Exception('Unsupported document type'); $grandTotalAmount = $prediction->totalAmount->value; $documentno = $prediction->invoiceNumber->value; $documentdate = $prediction->date->value; $invoiceCurrency = $prediction->locale->currency; $country = $prediction->locale->country; $expense = Expense::where('amount', $grandTotalAmount)->where("transaction_reference", $documentno)->whereDate("date", $documentdate)->first(); if (empty($expense)) { // The document does not exist as an expense // Handle accordingly $expense = ExpenseFactory::create($user->company()->id, $user->id); $expense->date = $documentdate; $expense->user_id = $user->id; $expense->company_id = $user->company->id; $expense->public_notes = $documentno; $expense->currency_id = Currency::whereCode($invoiceCurrency)->first()?->id || $user->company->settings->currency_id; $expense->save(); $this->saveDocuments([ $this->file, TempFile::UploadedFileFromRaw(strval($result->document), $documentno . "_mindee_orc_result.txt", "text/plain") ], $expense); $expense->saveQuietly(); $expense->uses_inclusive_taxes = True; $expense->amount = $grandTotalAmount; $counter = 1; foreach ($prediction->taxes as $taxesElem) { $expense->{"tax_amount$counter"} = $taxesElem->amount; $expense->{"tax_rate$counter"} = $taxesElem->rate; $counter++; } $vendor = null; $vendor_contact = VendorContact::where("company_id", $user->company()->id)->where("email", $prediction->supplierEmail)->first(); if ($vendor_contact) $vendor = $vendor_contact->vendor; if (!$vendor) $vendor = Vendor::where("company_id", $user->company()->id)->where("name", $prediction->supplierName)->first(); if ($vendor) { // Vendor found $expense->vendor_id = $vendor->id; } else { $vendor = VendorFactory::create($user->company()->id, $user->id); $vendor->name = $prediction->supplierName; $vendor->currency_id = Currency::whereCode($invoiceCurrency)->first()?->id; $vendor->phone = $prediction->supplierPhoneNumber; // $vendor->address1 = $address_1; // TODO: we only have the full address string from mindee returned // $vendor->address2 = $address_2; // $vendor->city = $city; // $vendor->postal_code = $postcode; $country = app('countries')->first(function ($c) use ($country) { return $c->iso_3166_2 == $country || $c->iso_3166_3 == $country; }); if ($country) $vendor->country_id = $country->id; $vendor->save(); if ($prediction->supplierEmail) { $vendor_contact = VendorContactFactory::create($user->company()->id, $user->id); $vendor_contact->vendor_id = $vendor->id; $vendor_contact->email = $prediction->supplierEmail; $vendor_contact->save(); } $expense->vendor_id = $vendor->id; } $expense->transaction_reference = $documentno; } else { // The document exists as an expense // Handle accordingly nlog("Document already exists"); $expense->private_notes = $expense->private_notes . ctrans("texts.edocument_import_already_exists", ["date" => time()]); } $expense->save(); return $expense; } private function checkLimits() { $user = auth()->user(); Cache::add('mindeeTotalDailyRequests', 0, now()->endOfDay()); Cache::add('mindeeTotalMonthlyRequests', 0, now()->endOfMonth()); Cache::add('mindeeAccountDailyRequests' . $user->company->account->id, 0, now()->endOfDay()); Cache::add('mindeeAccountMonthlyRequests' . $user->company->account->id, 0, now()->endOfMonth()); if (config('services.mindee.daily_limit') != 0 && Cache::get('mindeeTotalDailyRequests') > config('services.mindee.daily_limit')) throw new Exception('Mindee daily limit reached'); if (config('services.mindee.monthly_limit') != 0 && Cache::get('mindeeTotalMonthlyRequests') > config('services.mindee.monthly_limit')) throw new Exception('Mindee monthly limit reached'); if (config('services.mindee.account_daily_limit') != 0 && Cache::get('mindeeAccountDailyRequests' . $user->company->account->id) > config('services.mindee.account_daily_limit')) throw new Exception('Mindee daily limit reached for account: ' . $user->company->account->id); if (config('services.mindee.account_monthly_limit') != 0 && Cache::get('mindeeAccountMonthlyRequests' . $user->company->account->id) > config('services.mindee.account_monthly_limit')) throw new Exception('Mindee monthly limit reached for account: ' . $user->company->account->id); } private function incrementRequestCounts() { $user = auth()->user(); Cache::increment('mindeeTotalDailyRequests'); Cache::increment('mindeeTotalMonthlyRequests'); Cache::increment('mindeeAccountDailyRequests' . $user->company->account->id); Cache::increment('mindeeAccountMonthlyRequests' . $user->company->account->id); } }