diff --git a/database/seeds/DummyDataSeeder.php b/database/seeds/DummyDataSeeder.php
new file mode 100644
index 00000000..47196db2
--- /dev/null
+++ b/database/seeds/DummyDataSeeder.php
@@ -0,0 +1,508 @@
+faker = $faker;
+ $this->createsUser = $createsUser;
+ $this->createsCompany = $createsCompany;
+ $this->createsContact = $createsContact;
+ $this->createsAddress = $createsAddress;
+ $this->assignEmployeeProcessor = $assignEmployeeProcessor;
+ $this->createsDocument = $createsDocument;
+ $this->createsFiles = $createsFiles;
+ }
+
+
+ /**
+ * Run the database seeds.
+ *
+ * @return void
+ * @throws MalformedRequestException
+ * @throws AccessForbiddenException
+ * @throws RequestValidationException
+ */
+ public function run()
+ {
+ // Local Development Default Password Hash
+ $password = '123456abcabc';
+
+ // At the moment we only have 3 different user roles:
+ // RoleTypes::SUPER_ADMIN : Full access, at the moment is not attached to a company but should be in the future.
+ // RoleTypes::ADMIN : Full access except for some sensitive features that require higher level of approval, at the moment is not attached to a company but should be in the future.
+ // RoleTypes::USER : This is the customer, can only access their own orders only, must be attached to a company.
+
+ // User Status
+ // ApprovalStatus::PENDING_VERIFICATION : This should be the default status before the user verifies their email status, but currently this is not being implemented.
+ // ApprovalStatus::APPROVED : This is the status of users with verified emails.
+ // ApprovalStatus::SUSPENDED : This is the status if the users is blocked from the system, but currently this is not being implemented.
+
+
+ // =============================================== //
+ // Create CIEF Entities //
+ // =============================================== //
+
+ // create super admin
+ $userObject = new RegistrationObject($this->faker->name, 'super_admin@izyim.com', $password, $password,RoleTypes::SUPER_ADMIN, ApprovalStatus::APPROVED);
+ $this->createsUser->execute($userObject);
+
+ // create admin
+ $userObject = new RegistrationObject($this->faker->name, 'admin@izyim.com', $password, $password,RoleTypes::ADMIN, ApprovalStatus::APPROVED);
+ $this->createsUser->execute($userObject);
+
+ // create CIEF
+ $company_object = new CompanyObject('CIEF Worldwide Sdn Bhd', 'CIEF',CompanyType::COMPANY_BUSINESS,ApprovalStatus::APPROVED);
+ /** @var Company $company */
+ $company = $this->createsCompany->execute($company_object);
+
+ // =============================================== //
+ // Create Supplier Entities //
+ // =============================================== //
+ // supplier entities consist of 2 type of company module [BusinessType::FREIGHT_FORWARDER, BusinessType::FREIGHT_FORWARDER, BusinessType::WAREHOUSE]
+ // in this use case we are creating 3 supplier, with each supplier having 6 company modules, 1 BusinessType::FREIGHT_FORWARDER and 5 BusinessType::WAREHOUSE. 1 warehouse for each location.
+
+ for ($i = 1; $i <= 3; $i++) {
+ $supplierName = $this->faker->company;
+ $supplierReference = $this->faker->bothify('??-????');
+
+ $company_object = new CompanyObject($supplierName, $supplierReference,CompanyType::COMPANY_BUSINESS,ApprovalStatus::APPROVED);
+ /** @var Company $company */
+ $company = $this->createsCompany->execute($company_object);
+
+ $companyModuleObject = new CompanyModuleObject($supplierName, $supplierReference, '', '', BusinessType::FREIGHT_FORWARDER, ApprovalStatus::APPROVED);
+ $this->createsCompanyModule->execute($company, $companyModuleObject);
+
+ // create supplier warehouses
+ foreach(['Guangzhou', 'Yiwu', 'Klang', 'Sabah', 'Sarawak'] as $name){
+
+ $warehouseReference = '';
+ $isChina = false;
+
+ switch($name) {
+ case 'Guangzhou': $warehouseReference = 'GZ-V0'.$i; $isChina = true; break;
+ case 'Yiwu': $warehouseReference = 'YY-V0'.$i; $isChina = true; break;
+ case 'Klang': $warehouseReference = 'KL-V0'.$i; break;
+ case 'Sabah': $warehouseReference = 'SB-V0'.$i; break;
+ case 'Sarawak':$warehouseReference = 'SRW-V0'.$i; break;
+ }
+
+ $companyModuleObject = new CompanyModuleObject($name, $warehouseReference, '', '', BusinessType::WAREHOUSE, ApprovalStatus::APPROVED);
+ /** @var CompanyModule $companyModule */
+ $companyModule = $this->createsCompanyModule->execute($company, $companyModuleObject);
+
+ $address = new AddressObject( $this->faker->streetAddress, $this->faker->streetAddress, $isChina ? 2 : 1, $isChina ? 35 : 15, $isChina ? 633 : 412, $isChina ? 510450 : 41400, AddressType::DELIVERY, ApprovalStatus::APPROVED);
+ $this->createsAddress->execute($companyModule, $address);
+
+ $contact = new ContactObject($this->faker->name, $this->faker->phoneNumber, '', '');
+ $this->createsContact->execute($companyModule, $contact);
+ }
+ }
+
+
+ // =============================================== //
+ // Create Customer //
+ // =============================================== //
+ // 1. create user
+ // 2. create company
+
+ // 3. Attach Employee
+ // 4. create contact
+ // 5. create Address
+
+ // 6. identification verification
+
+ // =============================================== //
+ // Wallet //
+ // =============================================== //
+
+ // 7. top up wallet
+
+ // =============================================== //
+ // Order Workflow //
+ // =============================================== //
+
+ // 8. create recipient bank
+ // 9. create booking
+ // 10. make payment (Manual, FPX, Wallet)
+ // 11. approve payment (For manual payments only) * N
+ // 12. create supplier order
+ // 13. upload china payment proof (outsource * N)
+ // 14. create purchase order (maybe outsource)
+ // 15. approve purchase order ()
+ // 16. generate invoice
+
+ // generate random number of users
+ for($userLoop=1; $userLoop <= rand(20, 50); $userLoop++) {
+
+ // === //
+ // 1 // ========== //
+ // Create user //
+ // ================= //
+ $customerName = $this->faker->name;
+ $customerEmail = $this->faker->email;
+ $userObject = new RegistrationObject($customerName, $customerEmail, $password, $password, RoleTypes::USER, ApprovalStatus::APPROVED);
+ /** @var User $user */
+ $user = $this->createsUser->execute($userObject);
+
+ // === //
+ // 2 // ========== //
+ // Create Company //
+ // ================= //
+
+ // company reference is called marking, it is the human readable id.
+
+ // CompanyTypes
+ // CompanyType::COMPANY_BUSINESS : For SME Business Entities and requires SSM for identity verification.
+ // CompanyType::PERSONAL_BUSINESS : For Personal Entities and requires IC for identity verification, and the company name will follow the customer name in this case.
+
+ // Company Status
+ // ApprovalStatus::APPROVED : This is the default status of registered company.
+ // ApprovalStatus::SUSPENDED : This is the status if the company is blocked from releasing packages from warehouse due to pending verification.
+
+ $isCompany = $this->faker->numberBetween(0, 1);
+ $companyName = $isCompany ? $this->faker->company : $customerName;
+
+ $company_object = new CompanyObject($companyName,
+ mt_rand(1000, 9999).(new GeneratesInitials())->name($companyName)->length(3)->generate(),
+ $isCompany ? CompanyType::COMPANY_BUSINESS : CompanyType::PERSONAL_BUSINESS,
+ ApprovalStatus::APPROVED);
+
+ /** @var Company $company */
+ $company = $this->createsCompany->execute($company_object);
+
+ // === //
+ // 3 // ===========//
+ // Attach Employee //
+ // ==================//
+ // employees are attached to company modules not companies, because an employee maybe working for one or many "Departments".
+ $Object = new EmploymentObject($company, $user);
+ $this->assignEmployeeProcessor->execute($Object);
+
+ // === //
+ // 4 // ========== //
+ // Create Contact //
+ // ================= //
+ // Contacts uses eloquent polymorphic relationship to declare its owner. and for this use case it will be attached to the company not the company module.
+ $contactObject = new ContactObject($company->id, $customerName, $this->faker->phoneNumber, $customerEmail, null, $this->faker->bothify('??#####'));
+ $this->createsContact->execute($contactObject);
+
+ // === //
+ // 5 // ========== //
+ // Create Address //
+ // ================= //
+ // Addresses uses eloquent polymorphic relationship to declare its owner. and for this use case it will be attached to the company module.
+ // an address has at least 1 contact for the PIC.
+ // there is 1 type of address we use:
+ // AddressType::BILLING : for the invoice billing address
+
+ // create delivery address
+ $addressObject = new AddressObject($this->faker->streetAddress, '', 1, $this->faker->numberBetween(1, 15), $this->faker->numberBetween(1, 442), $this->faker->postcode);
+ /** @var Address $address */
+ $address = $this->createsAddress->execute($company, $addressObject);
+
+ // === //
+ // 6 // ====================== //
+ // identification verification //
+ // ============================== //
+ // please refer to company types section for more insight
+ $object = new DocumentObject($isCompany ? DocumentType::SSM_REGISTRATION : DocumentType::IDENTITY_CARD, ['data:image/png;base64,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'],
+ $isCompany ? $this->faker->bothify('SSM-#######') : $this->faker->bothify('############'), ApprovalStatus::APPROVED, 'identifications');
+ /** @var Document $document */
+ $document = $this->createsDocument->execute($company, $object);
+ $this->createsFiles->execute($document, $object);
+
+ // === //
+ // 7 // ========= //
+ // top up wallet //
+ // ================ //
+ // when a customer tries to top up their wallet, if the wallet doesn't already exist it will be automatically created.
+ // wallet credit can be used to pay for transfer orders to enjoy better conversion rates.
+ // wallet top-ups can only be performed using FPX at the moment. but super admin can manually credit or debit credit to a customer's wallet
+
+ // The transaction table is considered the most confusing part of our database because it is being used by multiple model using a polymorphic relationship
+ // and is used for many use cases in our application which is an unintended flaw, and we are looking for ways to improve it.
+
+
+ // A wallet top up is TransactionType::TOP_UP, there are many types of transactions used by a wallet:
+ // TransactionType::TOP_UP : represent a top-up amount to a wallet;
+ // TransactionType::PAYMENT : represent payment out of the wallet;
+ // TransactionType::CREDIT_NOTE : represent a manual top-up to a wallet, and can only be performed by super admin;
+ // TransactionType::CREDIT_NOTE : represent a deduction from a wallet, and can only be performed by super admin;
+ // TransactionType::WITHDRAW : represent a customer withdrawing credit out of a wallet to a bank account (refund);
+
+
+ // top up only some customers
+ $shouldTopUp = $this->faker->numberBetween(0, 1);
+ if($shouldTopUp) {
+ $object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute());
+ /** @var Wallet $wallet */
+ $wallet = $this->createsWallet->execute($object, $company);
+
+ $amount = $this->faker->numberBetween(10, 300000);
+ $billNumber = $this->generatesTransactionBillNumber->execute('TOPUP-');
+
+ // create billplz bill using api, we will skip this part in the seed.
+ $billPlzBill = $this->faker->bothify('???#####');
+
+ $transaction_object = new TransactionObject($billNumber, TransactionType::TOP_UP, 1, $company->id, 1, PaymentMethodType::PAYMENT_GATEWAY, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], $billPlzBill);
+
+ /** @var Transaction $transaction */
+ $transaction = $this->createsTransaction->execute($wallet, $transaction_object);
+
+
+ // on billplz callback url
+ $status = $this->faker->randomElement([ApprovalStatus::APPROVED, ApprovalStatus::REJECTED]);
+ $this->updatesTransactionStatus->execute($transaction, $status);
+ if($status === ApprovalStatus::APPROVED) {
+ $this->updatesWalletBalance->execute($wallet, $amount);
+ }
+ }
+
+ // === //
+ // 8 // ========================== //
+ // Create Recipient Bank Accounts //
+ // ================================= //
+ // bank accounts are used to store bank account details, and can be used in a variety of ways
+ // Bank types:
+ // 1. PERSONAL : belong to the same entity
+ // 2. EXTERNAL : Doesn't belong to the entity, belongs to an external entity;
+ // 3. ALIPAY : : Is an external entity, but flag the type of bank as alipay e-wallet;
+ //
+ // here are some of the current use cases for banks in our application:
+ // 1. Recipient bank (EXTERNAL) (the account the customer is requesting to transfer funds to)
+ // 2. AliPay Transfer (EXTERNAL) (the account the customer is requesting to transfer funds to when bank type is ALIPAY)
+ // 3. Refund bank (PERSONAL) (the account the customer is requesting his order refunds to be transferred to)
+ $bank_object = new BankObject($company->id, $this->faker->numberBetween(2, 3),
+ $this->faker->bank, $this->faker->name, $this->faker->bankAccountNumber,
+ $this->faker->city, null, null,
+ 2, $this->faker->company);
+
+ // todo create multiple bank accounts with multiple types
+ $bank = $this->createsBank->execute($bank_object);
+
+ // generate random number of bookings
+ for($orderLoop=1; $orderLoop <= rand(1, 30); $orderLoop++) {
+
+ // === //
+ // 9 // ========= //
+ // Create Booking //
+ // ================ //
+ // A booking is simply a transfer order to a supplier/manufacturer bank account overseas
+ // to pay for goods they are buying from overseas. the booking is not proceed until the
+ // customer requests to make a payment, when the customer start the payment process he
+ // will receive a quote for the cost to transfer the booked amount (e.g. 100 USD) in RM
+
+ // bookings require 2 actions from the customer to be completed
+ // 1. Make Full payment **
+ // 2. Provide Purchase Order (itemized list of the products they are buying)
+
+ // ** A booking will be the sum of payments transferred to one bank account
+ // but can be partially paid (e.g. 1000 USD can be paid: $300 deposit + $700 balance)
+ // A shipping label can be re-used, and each batch that arrives at the supplier warehouse
+ // is referred to as a packing list. more on this later.
+
+ // service types are configured by the super admin from the settings
+ // it will include things like conversion rates, service charge, etc..
+ // and can be used to place different type of transfer orders (e.g. 1 day transfer, 3 days transfer, 1688 Payment)
+
+ // randomly selects a service type
+ $service = ServiceType::where('reference', $this->faker->numberBetween(1, 3))->first();
+
+ // Booking human readable id
+ $reference = $this->generatesBookingMarking->execute();
+
+ // random currency booking (CNY, USD)
+ $bookedCurrency = $this->faker->numberBetween(2, 3);
+ $object = new BookingObject($service->id, $bank->id, $reference, $this->faker->numberBetween(10, 300000), $bookedCurrency, $bookedCurrency, 1);
+
+ $booking = $this->createsBooking->execute($company, $object);
+
+
+ // === //
+ // 10 // ====== //
+ // make payment //
+ // ============== //
+ // There are few type of transactions related to a booking:
+ // TransactionType::PAYMENT : is used for 2 type of use cases (1. payments to transfer orders, 2. payment out of wallet) and is attached to a booking;
+ // TransactionType::BILL : is to represent the payment out to CIEF currency supplier (expenses) and is attached to a transaction of type TransactionType::PAYMENT;
+ // TransactionType::TRANSFER_FEE : is to represent the transfer fee charged by CIEF currency supplier is attached to a transaction type TransactionType::BILL;
+ // TransactionType::REFUND : is to represent a request for refund on a payment, and is attached to a transaction type TransactionType::PAYMENT;
+
+ // todo make payment
+ // todo approve payment
+
+ // todo create supplier order
+ // when processing a customer order, we will place an order with one of our currency supplier which will generate a transaction type TransactionType::BILL
+ // and attach it to the customer payment TransactionType::PAYMENT, and it will update the TransactionType::PAYMENT status to ApprovalStatus::COMPLETED
+
+ // todo upload china payment proof
+ // when our currency supplier completes the transfer they will send us the bank slip as proof of payment, then the admin user
+ // will upload the bank slip document and attaching it to transaction type TransactionType::BILL
+
+ // todo create purchase order
+ // creating the purchase order can happen before or after the payment is made, the customer needs to fill up the list of product
+ // they are buying and attaching it to the booking, a purchase order is a transaction of type TransactionType::PURCHASE_ORDER
+ // todo approve purchase order
+
+ // todo generate invoice
+ // the invoicing documents will be generated once they 2 conditions are met:
+ // 1. Full payment completed (completed is flagged when the china payment proof is uploaded)
+ // 2. The purchase order is filled and approved (when the purchase order is not filled for more than 2 months the system will automatically generate a random products for Purchase order to close the order)
+
+ // once the invoice is generated the transaction table will include 2 new transaction type TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVERY
+ // and for documents will be generated and attached to the booking.
+ // once this process is complete the booking status will update to ApprovalStatus::COMPLETED
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/resources/views/vendor/js.blade.php b/resources/views/vendor/js.blade.php
index 41482a0d..97df1105 100644
--- a/resources/views/vendor/js.blade.php
+++ b/resources/views/vendor/js.blade.php
@@ -8,6 +8,6 @@
-
+
-{{--END VENDOR JS--}}
\ No newline at end of file
+{{--END VENDOR JS--}}