We'll be back soon!
-Sorry for the inconvenience but we're performing some maintenance at the moment. We'll be back online shortly!
+{{ config('maintenance.title') }}
+
+ {{ config('maintenance.message') }}
— CIEF IZYIM
diff --git a/.env.example b/.env.example
index ae852c04..47f16055 100644
--- a/.env.example
+++ b/.env.example
@@ -66,3 +66,7 @@ COMMANDS_V2_ENABLED=false
STORAGE_FEE_LAUNCH_DATE="2023-12-11 00:00:00"
SST_START_DATE="2024-04-01 00:00:00"
+
+E_INVOICE_START_DATE="2025-07-01 00:00:00"
+MAINTENANCE_MESSAGE_TITLE="We'll be back online on 00:00 1/7/2025"
+MAINTENANCE_MESSAGE="Sorry for the inconvenience but we're performing some maintenance at the moment."
diff --git a/app/Classes/Exceptions/CriteriaNotFulfilledException.php b/app/Classes/Exceptions/CriteriaNotFulfilledException.php
new file mode 100644
index 00000000..da105690
--- /dev/null
+++ b/app/Classes/Exceptions/CriteriaNotFulfilledException.php
@@ -0,0 +1,14 @@
+whereNotIn('type', $value);
+ }
+
+}
diff --git a/app/Classes/Modules/Addresses/ControllersLogic/ListAddressesLogic.php b/app/Classes/Modules/Addresses/ControllersLogic/ListAddressesLogic.php
index 71e3b80d..148f7f67 100644
--- a/app/Classes/Modules/Addresses/ControllersLogic/ListAddressesLogic.php
+++ b/app/Classes/Modules/Addresses/ControllersLogic/ListAddressesLogic.php
@@ -6,6 +6,7 @@ namespace App\Classes\Modules\Addresses\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Addresses\Services\ListsAddresses;
use App\Classes\Modules\Addresses\Standards\Rules\CanListAddresses;
+use App\Classes\ValueObjects\Constants\AddressType;
use App\Http\Resources\AddressResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
@@ -51,13 +52,12 @@ class ListAddressesLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
-
$this->canListAddresses->passes();
- $query = $this->listsAddresses->execute($this->listsAddresses->deserializeFilters($request->input('filters')));
+ //$query = $this->listsAddresses->execute($this->listsAddresses->deserializeFilters($request->input('filters')));
+ $query = $this->listsAddresses->execute(array_merge($this->listsAddresses->deserializeFilters($request->input('filters')), ['type_not_in' => [AddressType::E_INVOICE]]));
return $this->collectionResponse(AddressResource::collection($query));
-
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php b/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php
index f1d79e53..7c6ae8b0 100644
--- a/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php
+++ b/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php
@@ -23,7 +23,7 @@ class AddressObject implements DataTransferObject
/** @var int */
private $districtId;
- /** @var int */
+ /** @var string */
private $postCode;
/** @var int */
@@ -42,12 +42,12 @@ class AddressObject implements DataTransferObject
* @param int $countryId
* @param int $stateId
* @param int $districtId
- * @param int $postCode
+ * @param string $postCode
* @param int $type
* @param int $status
* @param null|string $reference
*/
- public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, int $postCode, int $type, int $status, ?string $reference = null)
+ public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, string $postCode, int $type, int $status, ?string $reference = null)
{
$this->streetOne = $streetOne;
$this->streetTwo = $streetTwo;
@@ -101,9 +101,9 @@ class AddressObject implements DataTransferObject
}
/**
- * @return int
+ * @return string
*/
- public function getPostCode(): int
+ public function getPostCode(): string
{
return $this->postCode;
}
@@ -133,4 +133,4 @@ class AddressObject implements DataTransferObject
}
-}
\ No newline at end of file
+}
diff --git a/app/Classes/Modules/Addresses/Services/UpsertsAddress.php b/app/Classes/Modules/Addresses/Services/UpsertsAddress.php
new file mode 100644
index 00000000..08bc26d4
--- /dev/null
+++ b/app/Classes/Modules/Addresses/Services/UpsertsAddress.php
@@ -0,0 +1,40 @@
+addresses()->where('id', $id)->first() ?? new Address();
+
+ $model->reference = $object->getReference();
+ $model->street_one = $object->getStreetOne();
+ $model->street_two = $object->getStreetTwo();
+ $model->country_id = $object->getCountryId();
+ $model->state_id = $object->getStateId();
+ $model->district_id = $object->getDistrictId();
+ $model->postcode = $object->getPostCode();
+ $model->status = $object->getStatus();
+ $model->type = $object->getType();
+
+ return $this->handler($addressable->addresses(), $model);
+ }
+}
diff --git a/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php b/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php
new file mode 100644
index 00000000..30f7642c
--- /dev/null
+++ b/app/Classes/Modules/Companies/ControllersLogic/FetchCompanyEInvoiceInfoLogic.php
@@ -0,0 +1,69 @@
+ 'Retrieved Company E-Invoice Info',
+ 'message' => 'You have successfully retrieved a Company E-Invoice Info'
+ ];
+ }
+
+ /** @var CanFetchCompany */
+ private $canFetchCompany;
+
+ /** @var FetchesCompany */
+ private $fetchesCompany;
+
+ /**
+ * FetchCompanyEInvoiceInfoLogic constructor.
+ * @param CanFetchCompany $canFetchCompany
+ * @param FetchesCompany $fetchesCompany
+ */
+ public function __construct(CanFetchCompany $canFetchCompany, FetchesCompany $fetchesCompany)
+ {
+ $this->canFetchCompany = $canFetchCompany;
+ $this->fetchesCompany = $fetchesCompany;
+ }
+
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $this->canFetchCompany->passes();
+
+ $company = $this->fetchesCompany->execute(['id' => $request->route('id')]);
+ $eInvoiceInfo = $company->companyModules()->first()->addresses()->where('type', '=', AddressType::E_INVOICE)->latest()->first();
+
+ if($eInvoiceInfo){
+ $eInvoiceInfo->tin = $company->tin;
+ $eInvoiceInfo->msic_code = $company->msic_code;
+ $eInvoiceInfo->e_invoice = $company->e_invoice;
+ }
+ else{
+ return $this->response([]);
+ }
+
+ return $this->resourceResponse(new EInvoiceInfoResource($eInvoiceInfo));
+ }
+}
diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php
new file mode 100644
index 00000000..599d770f
--- /dev/null
+++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyDetailsLogic.php
@@ -0,0 +1,153 @@
+ 'Update Company Details',
+ 'message' => 'You have successfully updated the Company Details'
+ ];
+ }
+ /** @var CanUpdateCompany */
+ private $canUpdateCompany;
+
+ /** @var UpdatesCompany */
+ private $updatesCompany;
+
+ /** @var FetchesCompany */
+ private $fetchesCompany;
+
+ /** @var UpdatesCompanyDebtor */
+ private $updatesCompanyDebtor;
+
+ /** @var CanCreateAddress */
+ private $canCreateAddress;
+
+ /** @var FetchesDistrict */
+ private $fetchesDistrict;
+
+ /** @var UpsertsAddress */
+ private $upsertsAddress;
+
+ /** @var UpdatesCompanyEInvoiceInfo */
+ private $updatesCompanyEInvoiceInfo;
+
+ /** @var UpdatesCompanyModuleName */
+ private $updatesCompanyModuleName;
+
+ /** @var FetchesDocument */
+ private $fetchesDocument;
+
+ /** @var UpdatesDocumentReference */
+ private $updatesDocumentReference;
+
+ /**
+ * UpdateCompanyDetailsLogic constructor.
+ * @param CanUpdateCompany $canUpdateCompany
+ * @param UpdatesCompany $updatesCompany
+ * @param FetchesCompany $fetchesCompany
+ * @param UpdatesCompanyDebtor $updatesCompanyDebtor
+ * @param CanCreateAddress $canCreateAddress
+ * @param FetchesDistrict $fetchesDistrict
+ * @param UpsertsAddress $upsertsAddress
+ * @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo;
+ * @param FetchesDocument $fetchesDocument
+ * @param UpdatesDocumentReference $updatesDocumentReference
+ *
+ */
+ public function __construct(
+ CanUpdateCompany $canUpdateCompany,
+ UpdatesCompany $updatesCompany,
+ FetchesCompany $fetchesCompany,
+ UpdatesCompanyDebtor $updatesCompanyDebtor,
+ CanCreateAddress $canCreateAddress,
+ FetchesDistrict $fetchesDistrict,
+ UpsertsAddress $upsertsAddress,
+ UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo,
+ UpdatesCompanyModuleName $updatesCompanyModuleName,
+ FetchesDocument $fetchesDocument,
+ UpdatesDocumentReference $updatesDocumentReference
+ )
+ {
+ $this->canUpdateCompany = $canUpdateCompany;
+ $this->updatesCompany = $updatesCompany;
+ $this->fetchesCompany = $fetchesCompany;
+ $this->updatesCompanyDebtor = $updatesCompanyDebtor;
+ $this->canCreateAddress = $canCreateAddress;
+ $this->fetchesDistrict = $fetchesDistrict;
+ $this->upsertsAddress = $upsertsAddress;
+ $this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo;
+ $this->updatesCompanyModuleName = $updatesCompanyModuleName;
+ $this->fetchesDocument = $fetchesDocument;
+ $this->updatesDocumentReference = $updatesDocumentReference;
+ }
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws ErrorException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $dto = new UpdateCompanyDetailsDTO($request->all());
+ $object = new CompanyObject($dto->name, $dto->reference, $dto->type);
+
+ $this->canUpdateCompany->passes($object);
+ $company = $this->fetchesCompany->execute(['id' => $request->route('id')]);
+
+ $this->updatesCompanyModuleName->execute($company->companyModules()->first(), $object->getName());
+
+ //Update Name and Debtor, Type
+ $company = $this->updatesCompany->execute($company, $object);
+
+ if ($request->input('debtor') || $company->first()->debtor !== null) {
+ $this->updatesCompanyDebtor->execute($company, $request->input('debtor'));
+ }
+
+ //Update EInvoice Related Info
+ if($company->e_invoice){
+ $district = $this->fetchesDistrict->execute(['id' => $dto->districtId]);
+ $addObj = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode, AddressType::E_INVOICE, ApprovalStatus::APPROVED, 'E-Invoice');
+
+ $this->canCreateAddress->passes($addObj);
+
+ $this->upsertsAddress->execute($company->companyModules()->first(), $addObj, $dto->addressId);
+ $this->updatesCompanyEInvoiceInfo->execute($company, $dto->tin, $dto->msicCode);
+ }
+
+ //Update Identification Card / SSM Registration
+ if($dto->identificationId){
+ $document = $this->fetchesDocument->execute(['id' => $dto->identificationId]);
+ $this->updatesDocumentReference->execute($document, $dto->identificationReference);
+ }
+
+ return $this->resourceResponse(new CompanyResource($company));
+ }
+}
+
diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php
new file mode 100644
index 00000000..319fa1a2
--- /dev/null
+++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceInfoLogic.php
@@ -0,0 +1,109 @@
+ 'EInvoice Info Update',
+ 'message' => 'You have successfully updated company E-Invoice information'
+ ];
+ }
+
+ /** @var CanCreateAddress */
+ private $canCreateAddress;
+
+ /** @var FetchesDistrict */
+ private $fetchesDistrict;
+
+ /** @var FetchesCompanyModule */
+ private $fetchesCompanyModule;
+
+ /** @var CreatesAddress */
+ private $createsAddress;
+
+ /** @var RuleEvaluator */
+ private $ruleEvaluator;
+
+ /** @var UpdatesCompanyEInvoiceInfo */
+ private $updatesCompanyEInvoiceInfo;
+
+ /** @var CanPassEInvoicePromptedRule */
+ private $canPassEInvoicePromptedRule;
+
+ /**
+ * UpdateCompanyEInvoiceInfoLogic constructor.
+ * @param CanCreateAddress $canCreateAddress
+ * @param FetchesDistrict $fetchesDistrict
+ * @param FetchesCompanyModule $fetchesCompanyModule
+ * @param CreatesAddress $createsAddress
+ * @param RuleEvaluator $ruleEvaluator;
+ * @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo;
+ * @param CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule
+ */
+ public function __construct(CanCreateAddress $canCreateAddress, FetchesDistrict $fetchesDistrict, FetchesCompanyModule $fetchesCompanyModule, CreatesAddress $createsAddress, RuleEvaluator $ruleEvaluator, UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule)
+ {
+ $this->canCreateAddress = $canCreateAddress;
+ $this->fetchesDistrict = $fetchesDistrict;
+ $this->fetchesCompanyModule = $fetchesCompanyModule;
+ $this->createsAddress = $createsAddress;
+ $this->ruleEvaluator = $ruleEvaluator;
+ $this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo;
+ $this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
+ }
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $dto = new EInvoiceInfoDTO($request->all());
+ $result = $this->ruleEvaluator->evaluate([
+ $this->canPassEInvoicePromptedRule,
+ ], $dto);
+
+ if ($result->failed()) {
+ throw new CriteriaNotFulfilledException("- " . implode("
- ", $result->messages()));
+ }
+
+ $district = $this->fetchesDistrict->execute(['id' => $dto->districtId]);
+ $object = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode, AddressType::E_INVOICE, ApprovalStatus::APPROVED, 'E-Invoice');
+
+ //Update Address
+ $this->canCreateAddress->passes($object);
+ $companyModule = $this->fetchesCompanyModule->execute(['id' => $dto->companyModuleId]);
+ $this->createsAddress->execute($companyModule, $object);
+
+ //Update tin, msic code
+ $this->updatesCompanyEInvoiceInfo->execute($companyModule->company, $dto->tin, $dto->msicCode);
+
+ return $this->response([]);
+ }
+}
diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php
new file mode 100644
index 00000000..a065802d
--- /dev/null
+++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyEInvoiceRequestLogic.php
@@ -0,0 +1,59 @@
+ 'Updated EInvoice Request',
+ 'message' => 'You have successfully updated company E-Invoice request'
+ ];
+ }
+
+ /** @var FetchesCompanyModule */
+ private $fetchesCompanyModule;
+
+ /** @var UpdatesCompanyEInvoiceRequest */
+ private $updatesCompanyEInvoiceRequest;
+
+
+ /**
+ * UpdateCompanyEInvoiceRequestLogic constructor.
+ * @param FetchesCompanyModule $fetchesCompanyModule
+ * @param UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest
+ */
+ public function __construct(FetchesCompanyModule $fetchesCompanyModule, UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest)
+ {
+ $this->fetchesCompanyModule = $fetchesCompanyModule;
+ $this->updatesCompanyEInvoiceRequest = $updatesCompanyEInvoiceRequest;
+ }
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $dto = new EInvoiceRequestDTO($request->all());
+ $companyModule = $this->fetchesCompanyModule->execute(['id' => $dto->companyModuleId]);
+ $this->updatesCompanyEInvoiceRequest->execute($companyModule->company, $dto->eInvoiceRequest);
+
+ return $this->response([]);
+ }
+}
diff --git a/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php
new file mode 100644
index 00000000..15c105aa
--- /dev/null
+++ b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceInfoDTO.php
@@ -0,0 +1,43 @@
+tin = (string) ($data['tin'] ?? '');
+ $this->msicCode = (string) ($data['msic_code'] ?? '');
+ $this->districtId = (int) ($data['district_id'] ?? 0);
+ $this->stateId = (int) ($data['state_id'] ?? 0);
+ $this->companyModuleId = (int) ($data['company_module_id'] ?? 0);
+ $this->streetOne = (string) ($data['street_one'] ?? '');
+ $this->streetTwo = (string) ($data['street_two'] ?? '');
+ $this->postCode = (string) ($data['post_code'] ?? '');
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'tin' => $this->tin,
+ 'msic_code' => $this->msicCode,
+ 'district_id' => $this->districtId,
+ 'state_id' => $this->stateId,
+ 'company_module_id' => $this->companyModuleId,
+ 'street_one' => $this->streetOne,
+ 'street_two' => $this->streetTwo,
+ 'post_code' => $this->postCode,
+ ];
+ }
+}
diff --git a/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php
new file mode 100644
index 00000000..1c46f2df
--- /dev/null
+++ b/app/Classes/Modules/Companies/DataTransferObjects/EInvoiceRequestDTO.php
@@ -0,0 +1,25 @@
+eInvoiceRequest = $data['e_invoice_request'];
+ $this->companyModuleId = $data['company_module_id'];
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'e_invoice_request' => $this->eInvoiceRequest,
+ 'company_module_id' => $this->companyModuleId,
+ ];
+ }
+}
diff --git a/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php b/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php
new file mode 100644
index 00000000..beae10bd
--- /dev/null
+++ b/app/Classes/Modules/Companies/DataTransferObjects/UpdateCompanyDetailsDTO.php
@@ -0,0 +1,72 @@
+id = (int) ($data['id'] ?? 0);
+ $this->name = (string) ($data['name'] ?? '');
+ $this->debtor = (string) ($data['debtor'] ?? '');
+ $this->reference = (string) ($data['reference'] ?? '');
+ $this->type = (int) ($data['type'] ?? 0);
+
+ $this->tin = (string) ($data['tin'] ?? 0);
+ $this->msicCode = (string) ($data['msic_code'] ?? '');
+ $this->addressId = (int) ($data['address_id'] ?? 0);
+ $this->districtId = (int) ($data['district_id'] ?? 0);
+ $this->stateId = (int) ($data['state_id'] ?? 0);
+ $this->companyId = (int) ($data['company_id'] ?? 0);
+ $this->streetOne = (string) ($data['street_one'] ?? '');
+ $this->streetTwo = (string) ($data['street_two'] ?? '');
+ $this->postCode = (string) ($data['post_code'] ?? '');
+ $this->identificationReference = (string) ($data['identification_reference'] ?? '');
+ $this->identificationId = (int) ($data['identification_id'] ?? 0);
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'id' => $this->id,
+ 'name' => $this->name,
+ 'debtor' => $this->debtor,
+ 'reference' => $this->reference,
+ 'type' => $this->type,
+
+ 'tin' => $this->tin,
+ 'msic_code' => $this->msicCode,
+ 'address_id' => $this->addressId,
+ 'district_id' => $this->districtId,
+ 'state_id' => $this->stateId,
+ 'company_id' => $this->companyId,
+ 'street_one' => $this->streetOne,
+ 'street_two' => $this->streetTwo,
+ 'post_code' => $this->postCode,
+
+ 'identification_reference' => $this->identificationReference,
+ 'identification_id' => $this->identificationId,
+ ];
+ }
+}
diff --git a/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php
new file mode 100644
index 00000000..0a2c5cc5
--- /dev/null
+++ b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceInfo.php
@@ -0,0 +1,25 @@
+tin = $tin;
+ $model->msic_code = $msicCode;
+
+ return $this->handler($model);
+ }
+}
diff --git a/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php
new file mode 100644
index 00000000..bdef7fc8
--- /dev/null
+++ b/app/Classes/Modules/Companies/Services/UpdatesCompanyEInvoiceRequest.php
@@ -0,0 +1,29 @@
+e_invoice_requested_at)) {
+ if($eInvoice){
+ $model->e_invoice_requested_at = now();
+ }
+ }
+ $model->e_invoice = $eInvoice;
+
+ return $this->handler($model);
+ }
+}
diff --git a/app/Classes/Modules/Exports/Services/ExportsAllCustomersInfoForLarkSystem.php b/app/Classes/Modules/Exports/Services/ExportsAllCustomersInfoForLarkSystem.php
index c76f36f5..40294a21 100644
--- a/app/Classes/Modules/Exports/Services/ExportsAllCustomersInfoForLarkSystem.php
+++ b/app/Classes/Modules/Exports/Services/ExportsAllCustomersInfoForLarkSystem.php
@@ -2,18 +2,18 @@
namespace App\Classes\Modules\Exports\Services;
+use App\Models\Company;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
-use Maatwebsite\Excel\Concerns\WithHeadingRow;
use App\Classes\General\Eloquent\ApplyFiltersToQuery;
-use App\Models\Company;
-class ExportsAllCustomersInfoForLarkSystem implements WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, FromQuery
+class ExportsAllCustomersInfoForLarkSystem implements FromQuery, WithMapping, WithHeadings, ShouldAutoSize
{
use Exportable;
+
public function __construct() {}
public function headings(): array
@@ -25,33 +25,58 @@ class ExportsAllCustomersInfoForLarkSystem implements WithHeadings, WithHeadingR
'Email',
'Registration Date',
'Last Order Date',
+ 'Debtor Code',
+ 'Credit Term Customer',
'Custom Segments',
];
}
public function query()
{
- return (new ApplyFiltersToQuery())->execute(Company::query(), [
- 'has_business_module_type' => 1,
- ]);
+ return (new ApplyFiltersToQuery())->execute(
+ Company::query()->with([
+ 'companyModules.employees',
+ 'companyModules.connections.segments',
+ 'contacts'
+ ]),
+ ['has_business_module_type' => 1]
+ );
}
public function map($company): array
{
- $company_module = $company->companyModules()->first();
- $marking = $company_module->getMarking();
- $employees = $company_module->employees()->first();
+ $companyModule = $company->companyModules->first();
+ $marking = $companyModule ? $companyModule->getMarking() : '';
+ $creditTermCustomer = '';
+ if ($companyModule && $companyModule->connections->first()) {
+ $creditTermCustomer = $companyModule->connections->first()->is_credit_term ? 'YES' : 'NO';
+ }
- $data = [
+ $employeeEmail = '';
+ if ($companyModule && $companyModule->employees->first()) {
+ $employeeEmail = $companyModule->employees->first()->email;
+ }
+
+ $contactPhone = '';
+ if ($company->contacts->first()) {
+ $contactPhone = $company->contacts->first()->phone;
+ }
+
+ $segments = '';
+ if ($companyModule && $companyModule->connections->first()) {
+ $segments = $companyModule->connections->first()->segments->pluck('name')->implode(', ');
+ }
+
+ return [
$marking,
$company->name,
- $company->contacts()->first()->phone ?? '',
- $employees?->email ?? '',
- $company->created_at,
- $company->updated_at,
- $company_module->connections()->first()->segments()->pluck('name')->implode(', ')
+ $contactPhone,
+ $employeeEmail,
+ $company->created_at ? $company->created_at->toDateString() : '',
+ $company->updated_at ? $company->updated_at->toDateString() : '',
+ $company->debtor,
+ $creditTermCustomer,
+ $segments,
];
-
- return $data;
}
}
diff --git a/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php b/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php
new file mode 100644
index 00000000..9c690686
--- /dev/null
+++ b/app/Classes/Modules/Rules/ControllersLogic/CheckEInvoiceRuleLogic.php
@@ -0,0 +1,70 @@
+ 'Rule Check E-Invoice',
+ 'message' => 'You have successfully passed all rules evaluated'
+ ];
+ }
+
+ /** @var RuleEvaluator */
+ private $ruleEvaluator;
+
+ /** @var CanPassEInvoicePromptedRule */
+ private $canPassEInvoicePromptedRule;
+
+ /** @var CanPassTINRule */
+ private $canPassTINRule;
+
+ /**
+ * CheckEInvoiceRuleLogic constructor.
+ */
+ public function __construct(RuleEvaluator $ruleEvaluator, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule, CanPassTINRule $canPassTINRule)
+ {
+ $this->ruleEvaluator = $ruleEvaluator;
+ $this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
+ $this->canPassTINRule = $canPassTINRule;
+ }
+
+ /**
+ * @param Request $request
+ * @return JsonResponse
+ * @throws \App\Classes\Exceptions\AccessForbiddenException
+ * @throws \App\Classes\Exceptions\MalformedRequestException
+ * @throws \App\Classes\Exceptions\RequestValidationException
+ * @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
+ */
+ public function logic(Request $request) : JsonResponse
+ {
+ $dto = new CheckEInvoiceRuleDTO($request->all());
+
+ $result = $this->ruleEvaluator->evaluate([
+ $this->canPassEInvoicePromptedRule,
+ $this->canPassTINRule,
+ ], $dto);
+
+ if ($result->failed()) {
+ throw new CriteriaNotFulfilledException("- " . implode("
- ", $result->messages()));
+ }
+
+ return $this->resourceResponse(new RuleResource((object)$result));
+ }
+}
diff --git a/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php b/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php
new file mode 100644
index 00000000..c982aeb0
--- /dev/null
+++ b/app/Classes/Modules/Rules/DataTransferObjects/CheckEInvoiceRuleDTO.php
@@ -0,0 +1,22 @@
+companyModuleId = $data['company_module_id'];
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'company_module_id' => $this->companyModuleId,
+ ];
+ }
+}
diff --git a/app/Classes/Modules/Rules/Services/RuleEvaluator.php b/app/Classes/Modules/Rules/Services/RuleEvaluator.php
new file mode 100644
index 00000000..ac248a25
--- /dev/null
+++ b/app/Classes/Modules/Rules/Services/RuleEvaluator.php
@@ -0,0 +1,44 @@
+passes($object)) {
+ $success = false;
+ $messages[] = get_class($rule) . ' failed without exception';
+ }
+ } catch (AccessForbiddenException | RequestValidationException | CriteriaNotFulfilledException $e) {
+ $success = false;
+ $messages[] = $e->getMessage();
+ } catch (\Exception $e) {
+ $success = false;
+ $messages[] = 'Unexpected error in ' . get_class($rule) . ': ' . $e->getMessage();
+ }
+ }
+
+ return new RuleEvaluationResult($success, $messages);
+ }
+
+}
diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php
new file mode 100644
index 00000000..61d1dfcb
--- /dev/null
+++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassEInvoicePromptedRule.php
@@ -0,0 +1,57 @@
+fetchesCompanyModule = $fetchesCompanyModule;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function authorized($object): bool
+ {
+ return true;
+
+ }
+
+ /**
+ * @return bool
+ */
+ protected function validators($object): bool
+ {
+ return true;
+
+ }
+
+
+ /**
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ //Check if account requires E-Invoice
+ $companyModule = $this->fetchesCompanyModule->execute(['id' => $object->companyModuleId]);
+ if($companyModule->company->e_invoice === null){
+ throw new CriteriaNotFulfilledException("Please refresh page to answer question related to E-Invoice.");
+ }
+ return true;
+ }
+
+}
diff --git a/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php
new file mode 100644
index 00000000..5ec859cb
--- /dev/null
+++ b/app/Classes/Modules/Rules/Standards/Rules/CanPassTINRule.php
@@ -0,0 +1,55 @@
+fetchesCompanyModule = $fetchesCompanyModule;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function authorized($object): bool
+ {
+ return true;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function validators($object): bool
+ {
+ return true;
+ }
+
+
+ /**
+ * @return bool
+ */
+ protected function criteria($object): bool
+ {
+ //Check if TIN already provided if account requires E-Invoice
+ $companyModule = $this->fetchesCompanyModule->execute(['id' => $object->companyModuleId]);
+ if($companyModule->company->e_invoice === 1 && !$companyModule->company->tin){
+ throw new CriteriaNotFulfilledException("Please provide all requested E-Invoice Info.");
+ }
+ return true;
+ }
+
+}
diff --git a/app/Classes/ValueObjects/Constants/AddressType.php b/app/Classes/ValueObjects/Constants/AddressType.php
index 614b9774..b9952a3e 100644
--- a/app/Classes/ValueObjects/Constants/AddressType.php
+++ b/app/Classes/ValueObjects/Constants/AddressType.php
@@ -10,4 +10,6 @@ final class AddressType {
public const PICK_UP = 3;
+ public const E_INVOICE = 4;
+
}
diff --git a/app/Classes/ValueObjects/Response/RuleEvaluationResult.php b/app/Classes/ValueObjects/Response/RuleEvaluationResult.php
new file mode 100644
index 00000000..264eaf26
--- /dev/null
+++ b/app/Classes/ValueObjects/Response/RuleEvaluationResult.php
@@ -0,0 +1,30 @@
+success = $success;
+ $this->messages = $messages;
+ }
+
+ public function failed(): bool
+ {
+ return ! $this->success;
+ }
+
+ public function passed(): bool
+ {
+ return $this->success;
+ }
+
+ public function messages(): array
+ {
+ return $this->messages;
+ }
+}
diff --git a/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php b/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php
new file mode 100644
index 00000000..d506e24e
--- /dev/null
+++ b/app/Http/Controllers/Companies/FetchCompanyEInvoiceInfoController.php
@@ -0,0 +1,20 @@
+execute($request);
+ }
+}
diff --git a/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php b/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php
new file mode 100644
index 00000000..e8cbfd1c
--- /dev/null
+++ b/app/Http/Controllers/Companies/UpdateCompanyDetailsController.php
@@ -0,0 +1,21 @@
+execute($request);
+ }
+}
diff --git a/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php b/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php
new file mode 100644
index 00000000..9157e9de
--- /dev/null
+++ b/app/Http/Controllers/Companies/UpdateCompanyEInvoiceInfoController.php
@@ -0,0 +1,29 @@
+execute($request);
+ }
+
+ /**
+ * @param Request $request
+ * @param UpdateCompanyEInvoiceRequestLogic $logic
+ * @return JsonResponse
+ */
+ public function updateRequest(Request $request, UpdateCompanyEInvoiceRequestLogic $logic): JsonResponse {
+ return $logic->execute($request);
+ }
+}
diff --git a/app/Http/Controllers/Exports/ExportCompanyModuleSummaryController.php b/app/Http/Controllers/Exports/ExportCompanyModuleSummaryController.php
index 42bcc084..547698f8 100644
--- a/app/Http/Controllers/Exports/ExportCompanyModuleSummaryController.php
+++ b/app/Http/Controllers/Exports/ExportCompanyModuleSummaryController.php
@@ -87,7 +87,7 @@ class ExportCompanyModuleSummaryController
}
$exportsAllCustomersInfoForLarkSystem = new ExportsAllCustomersInfoForLarkSystem($request);
- $exportFileName = 'all_customers_info_for_lark_system.xls';
+ $exportFileName = 'shipping_all_customers_info_for_lark_system.xls';
$filesystemDriver = Storage::getDefaultDriver();
if ($filesystemDriver === 's3') {
diff --git a/app/Http/Controllers/Rules/CheckRuleController.php b/app/Http/Controllers/Rules/CheckRuleController.php
new file mode 100644
index 00000000..af95e185
--- /dev/null
+++ b/app/Http/Controllers/Rules/CheckRuleController.php
@@ -0,0 +1,19 @@
+execute($request);
+ }
+}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index ea5a6e9d..ef039b85 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -75,5 +75,6 @@ class Kernel extends HttpKernel
'storage.invoice.check.bytransactions' => \App\Http\Middleware\CheckForStorageInvoiceByTransactions::class,
'storage.invoice.check.bygroup' => \App\Http\Middleware\CheckForStorageInvoiceByGroup::class,
'storage.invoice.check.bypackinglists' => \App\Http\Middleware\CheckForStorageInvoiceByPackingLists::class,
+ 'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class, //cief todo: 90 - maintenance
];
}
diff --git a/app/Http/Middleware/EnsureUserIsAdmin.php b/app/Http/Middleware/EnsureUserIsAdmin.php
new file mode 100644
index 00000000..4dcd5225
--- /dev/null
+++ b/app/Http/Middleware/EnsureUserIsAdmin.php
@@ -0,0 +1,32 @@
+authenticate();
+ if(!in_array($user->type, RoleTypes::ADMIN_ROLES)){
+ return response()->view('errors.503', [], 503);
+ }
+ }
+
+ return $next($request);
+ }
+}
diff --git a/app/Http/Resources/AddressEInvoiceResource.php b/app/Http/Resources/AddressEInvoiceResource.php
new file mode 100644
index 00000000..d6e49801
--- /dev/null
+++ b/app/Http/Resources/AddressEInvoiceResource.php
@@ -0,0 +1,28 @@
+ $this->id,
+ 'street_one' => $this->street_one,
+ 'street_two' => $this->street_two,
+ 'district' => $this->district,
+ 'state' => $this->state,
+ 'post_code' => (string) $this->postcode,
+ 'country' => $this->country,
+ 'billing' => (int) $this->billing
+ ];
+ }
+}
diff --git a/app/Http/Resources/CompanyModuleResource.php b/app/Http/Resources/CompanyModuleResource.php
index 5ffc40f8..f48cbc43 100644
--- a/app/Http/Resources/CompanyModuleResource.php
+++ b/app/Http/Resources/CompanyModuleResource.php
@@ -51,6 +51,10 @@ class CompanyModuleResource extends JsonResource
'connections' => $this->connections,
'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())),
'debtor' => $this->company->debtor,
+ 'e_invoice' => $this->company->e_invoice,
+ 'tin' => $this->company->tin,
+ 'msic_code' => $this->company->msic_code,
+ 'address_einvoice' => $this->company->e_invoice ? new AddressEInvoiceResource($this->when($this->has('addresses'), $this->addresses->where('type', AddressType::E_INVOICE)->sortByDesc('created_at')->first())) : null,
];
}
diff --git a/app/Http/Resources/EInvoiceInfoResource.php b/app/Http/Resources/EInvoiceInfoResource.php
new file mode 100644
index 00000000..97483dd3
--- /dev/null
+++ b/app/Http/Resources/EInvoiceInfoResource.php
@@ -0,0 +1,31 @@
+ $this->id,
+ 'street_one' => $this->street_one,
+ 'street_two' => $this->street_two,
+ 'district' => $this->district,
+ 'state' => $this->state,
+ 'post_code' => (string) $this->postcode,
+ 'country' => $this->country,
+ 'billing' => (int) $this->billing,
+ 'msic_code' => (string) $this->msic_code,
+ 'tin' => (string) $this->tin,
+ 'e_invoice' => (int) $this->e_invoice,
+ ];
+ }
+}
diff --git a/app/Http/Resources/RuleResource.php b/app/Http/Resources/RuleResource.php
new file mode 100644
index 00000000..1fb42181
--- /dev/null
+++ b/app/Http/Resources/RuleResource.php
@@ -0,0 +1,22 @@
+ $this->success,
+ 'messages' => $this->messages,
+ ];
+ }
+}
diff --git a/config/maintenance.php b/config/maintenance.php
new file mode 100644
index 00000000..66376756
--- /dev/null
+++ b/config/maintenance.php
@@ -0,0 +1,6 @@
+ env('MAINTENANCE_MESSAGE_TITLE', "We'll be back soon!"),
+ 'message' => env('MAINTENANCE_MESSAGE', "Sorry for the inconvenience but we're performing some maintenance at the moment."),
+];
diff --git a/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php b/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php
new file mode 100644
index 00000000..ed5f2c58
--- /dev/null
+++ b/database/migrations/2025_06_15_192423_add_tin_to_companies_table.php
@@ -0,0 +1,38 @@
+string('tin')->nullable()->after('debtor');
+ $table->string('msic_code')->nullable()->after('debtor')->comment("5-digit code representing business activity");
+ $table->timestamp('e_invoice_requested_at')->nullable()->after('debtor');
+ $table->boolean('e_invoice')->nullable()->default(null)->after('debtor');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('companies', function (Blueprint $table) {
+ $table->dropColumn('tin');
+ $table->dropColumn('msic_code');
+ $table->dropColumn('e_invoice_requested_at');
+ $table->dropColumn('e_invoice');
+ });
+ }
+}
diff --git a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue
index b71287c5..bef39049 100644
--- a/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue
+++ b/resources/assets/vue/components/companies/elements/CustomerProfileComponent.vue
@@ -16,7 +16,8 @@
TIN
+{{ eInvoiceData.tin }}
+MSIC Code
+{{ eInvoiceData.msic_code }}
+Billing Address
+ + +TIN
+{{parameters.tin}}
+MSIC Code
+{{parameters.msic_code}}
+Billing Address
+{{parameters.street_one}} {{parameters.street_two}}, {{districts[parseFloat(parameters.district_id) - 1].text}} {{parameters.post_code}} {{states[parseFloat(parameters.state_id) - 1].text}}, Malaysia
+