mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
Merge branch 'dillon/110-period-lock-c' into vapor/development
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Bookings\Processors\RegenerateInvoiceBookingProcessor;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Classes\Jobs\Commands\V2;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Classes\Jobs;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Notifications\WelcomeVoucherEmail;
|
||||
use App\Models\User;
|
||||
use App\Models\Voucher;
|
||||
|
||||
@@ -183,8 +183,10 @@ class CreateCustomerLogic extends AbstractControllerLogic
|
||||
}
|
||||
}
|
||||
|
||||
// Track affiliate registration if user came from affiliate link
|
||||
$this->tracksAffiliateRegistration->execute($user, $request->get('tracking'));
|
||||
// Track affiliate registration if user came from affiliate link.
|
||||
// Prefer ?tracking= from request; fallback to cookie set by TrackAffiliateClick on /signup visit.
|
||||
$code = $request->get('tracking') ?? $request->cookie(\App\Classes\Modules\Affiliate\Services\TracksAffiliateClick::COOKIE_NAME);
|
||||
$this->tracksAffiliateRegistration->execute($user, $code);
|
||||
|
||||
return $this->response($this->authenticationProcessor->execute($request, false));
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ class CreateSystemUserLogic extends AbstractControllerLogic
|
||||
|
||||
$this->canCreateUser->passes($user_object);
|
||||
$user = $this->createsUser->execute($user_object);
|
||||
$token = $user->createToken('my-app-token', ['*'])->plainTextToken;
|
||||
return $this->response(['token' => $token]);
|
||||
// $token = $user->createToken('my-app-token', ['*'])->plainTextToken;
|
||||
// return $this->response(['token' => $token]);
|
||||
}
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
@@ -2,33 +2,58 @@
|
||||
|
||||
namespace App\Classes\Modules\Affiliate\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Affiliate\Services\CreatesAffiliate;
|
||||
use App\Classes\Modules\Affiliate\DataTransferObjects\AffiliateObject;
|
||||
use App\Classes\Modules\Affiliate\Standards\Rules\CanCreateAffiliate;
|
||||
use App\Http\Resources\AffiliateResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateAffiliateLogic
|
||||
class CreateAffiliateLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Created Affiliate',
|
||||
'message' => 'You have successfully created a new Affiliate Code'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanCreateAffiliate */
|
||||
private $canCreateAffiliate;
|
||||
|
||||
/** @var CreatesAffiliate */
|
||||
private $createsAffiliate;
|
||||
|
||||
/**
|
||||
* CreateAffiliateLogic constructor.
|
||||
* @param CanCreateAffiliate $canCreateAffiliate
|
||||
* @param CreatesAffiliate $createsAffiliate
|
||||
*/
|
||||
public function __construct(CreatesAffiliate $createsAffiliate)
|
||||
public function __construct(
|
||||
CanCreateAffiliate $canCreateAffiliate,
|
||||
CreatesAffiliate $createsAffiliate
|
||||
)
|
||||
{
|
||||
$this->canCreateAffiliate = $canCreateAffiliate;
|
||||
$this->createsAffiliate = $createsAffiliate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function execute(Request $request): JsonResponse
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
$code = $request->input('code');
|
||||
$code = $code !== null ? (string) $code : '';
|
||||
|
||||
|
||||
$isActive = $request->input('is_active', true);
|
||||
// Convert string 'true'/'false' to boolean if needed
|
||||
if (is_string($isActive)) {
|
||||
@@ -43,12 +68,13 @@ class CreateAffiliateLogic
|
||||
$isActive
|
||||
);
|
||||
|
||||
// Validate the affiliate object
|
||||
$this->canCreateAffiliate->passes($object);
|
||||
|
||||
// Create the affiliate
|
||||
$affiliate = $this->createsAffiliate->execute($object);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Affiliate code created successfully',
|
||||
'data' => $affiliate
|
||||
]);
|
||||
return $this->resourceResponse(new AffiliateResource($affiliate));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,23 +18,17 @@ class CreatesAffiliate extends AbstractUpdateRecord
|
||||
public function execute(AffiliateObject $object)
|
||||
{
|
||||
$code = $object->getCode();
|
||||
|
||||
|
||||
// Auto-generate code if not provided
|
||||
if (empty($code)) {
|
||||
$code = $this->generateUniqueCode();
|
||||
} else {
|
||||
// Validate uniqueness of user-provided code (including soft-deleted records)
|
||||
$existingAffiliate = Affiliate::where('code', $code)
|
||||
->whereNull('deleted_at')
|
||||
->first();
|
||||
|
||||
if ($existingAffiliate) {
|
||||
throw new \App\Classes\Exceptions\MalformedRequestException('Affiliate code already exists. Please choose a different code.');
|
||||
}
|
||||
// Uppercase the code for consistency
|
||||
$code = strtoupper($code);
|
||||
}
|
||||
|
||||
$model = new Affiliate();
|
||||
$model->code = $code;
|
||||
$model->code = strtoupper($code);
|
||||
$model->campaign_name = $object->getCampaignName();
|
||||
$model->campaign_description = $object->getCampaignDescription();
|
||||
$model->is_active = $object->getIsActive();
|
||||
@@ -48,19 +42,19 @@ class CreatesAffiliate extends AbstractUpdateRecord
|
||||
|
||||
/**
|
||||
* Generate a unique affiliate code
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateUniqueCode(): string
|
||||
{
|
||||
$maxAttempts = 10;
|
||||
$attempts = 0;
|
||||
|
||||
|
||||
do {
|
||||
// Increased from 12 to 16 characters for better uniqueness
|
||||
$code = Str::random(16);
|
||||
$attempts++;
|
||||
|
||||
|
||||
if ($attempts >= $maxAttempts) {
|
||||
// Fallback to UUID if we can't generate unique code
|
||||
$code = strtoupper(Str::substr(str_replace('-', '', Str::uuid()), 0, 16));
|
||||
|
||||
@@ -12,7 +12,7 @@ class TracksAffiliateOrder
|
||||
{
|
||||
/**
|
||||
* Track when a user with an affiliate code creates an order
|
||||
*
|
||||
*
|
||||
* @param Booking $booking
|
||||
* @return Affiliate|null
|
||||
*/
|
||||
@@ -48,22 +48,22 @@ class TracksAffiliateOrder
|
||||
// Check if this booking has already been counted
|
||||
// We'll use a KeyValuePair to track which bookings have been counted
|
||||
$kvpKey = 'affiliate_order_tracked_' . $affiliate->id;
|
||||
|
||||
|
||||
$existingKvp = $booking->attributesKVP()
|
||||
->where('key', $kvpKey)
|
||||
->exists();
|
||||
|
||||
|
||||
if ($existingKvp) {
|
||||
return $affiliate; // Already counted
|
||||
}
|
||||
|
||||
// Mark this booking as tracked
|
||||
$keyValuePairObject = new \App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject(
|
||||
$keyValuePairObject = new \App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject(
|
||||
$kvpKey,
|
||||
'1'
|
||||
);
|
||||
|
||||
$createsKeyValuePair = app()->make(\App\Classes\Modules\Accounts\Services\CreatesKeyValuePair::class);
|
||||
|
||||
$createsKeyValuePair = app()->make(\App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair::class);
|
||||
$createsKeyValuePair->execute($booking, $keyValuePairObject);
|
||||
|
||||
// Increment orders count atomically
|
||||
|
||||
@@ -13,12 +13,14 @@ class TracksAffiliateRegistration
|
||||
{
|
||||
/**
|
||||
* Track when a user registers with an affiliate code
|
||||
*
|
||||
*
|
||||
* @param User $user
|
||||
* @return Affiliate|null
|
||||
*/
|
||||
public function execute(User $user, string $code): ?Affiliate
|
||||
public function execute(User $user, ?string $code = null): ?Affiliate
|
||||
{
|
||||
// Log::info('TracksAffiliateRegistration::execute', ['user' => $user, 'code' => $code]);
|
||||
|
||||
if (!$code || !$this->isValidCode($code)) {
|
||||
Log::info('Code is not valid', ['code' => $code]);
|
||||
return null;
|
||||
@@ -65,7 +67,7 @@ class TracksAffiliateRegistration
|
||||
|
||||
/**
|
||||
* Validate affiliate code format
|
||||
*
|
||||
*
|
||||
* @param string $code
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Affiliate\Standards\Rules;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Affiliate\DataTransferObjects\AffiliateObject;
|
||||
use App\Classes\Modules\Affiliate\Standards\Validators\AffiliateCreateValidation;
|
||||
|
||||
class CanCreateAffiliate extends AbstractRule
|
||||
{
|
||||
/** @var AffiliateCreateValidation */
|
||||
private $affiliateCreateValidation;
|
||||
|
||||
/**
|
||||
* CanCreateAffiliate constructor.
|
||||
* @param AffiliateCreateValidation $affiliateCreateValidation
|
||||
*/
|
||||
public function __construct(AffiliateCreateValidation $affiliateCreateValidation)
|
||||
{
|
||||
$this->affiliateCreateValidation = $affiliateCreateValidation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AffiliateObject $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
// Authorization is handled by policy in controller
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AffiliateObject $object
|
||||
* @return bool
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return $this->affiliateCreateValidation->validate($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AffiliateObject $object
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
// No additional criteria needed for affiliate creation
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Affiliate\Standards\Validators;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractValidation;
|
||||
use App\Classes\Modules\Affiliate\DataTransferObjects\AffiliateObject;
|
||||
use App\Models\Affiliate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class AffiliateCreateValidation extends AbstractValidation
|
||||
{
|
||||
/**
|
||||
* @param AffiliateObject $object
|
||||
* @return array
|
||||
*/
|
||||
protected function data($object): array
|
||||
{
|
||||
return [
|
||||
'code' => $object->getCode(),
|
||||
'campaign_name' => $object->getCampaignName(),
|
||||
'campaign_description' => $object->getCampaignDescription(),
|
||||
'is_active' => $object->getIsActive(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function rules(): array
|
||||
{
|
||||
return [
|
||||
'code' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'min:3',
|
||||
'max:255',
|
||||
'regex:/^[a-zA-Z0-9_-]+$/',
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!empty($value)) {
|
||||
$uppercaseCode = strtoupper($value);
|
||||
$exists = Affiliate::whereRaw('UPPER(code) = ?', [$uppercaseCode])
|
||||
->whereNull('deleted_at')
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
$fail('Affiliate code already exists. Please choose a different code.');
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
'campaign_name' => 'required|string|max:255',
|
||||
'campaign_description' => 'nullable|string|max:65535',
|
||||
'is_active' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function messages(): array
|
||||
{
|
||||
return [
|
||||
'code.regex' => 'The affiliate code may only contain letters, numbers, hyphens, and underscores.',
|
||||
'code.min' => 'The affiliate code must be at least 3 characters.',
|
||||
'campaign_name.required' => 'A campaign name is required.',
|
||||
'campaign_name.max' => 'The campaign name cannot exceed 255 characters.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Banks\Services\UpdatesBank;
|
||||
use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank;
|
||||
use App\Classes\Modules\Banks\DataTransferObjects\BankObject;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\Bank;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanCreateBooking;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -62,6 +62,8 @@ class CreateBookingLockLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanCreateBookingLock
|
||||
|
||||
// $password = $request->input('password');
|
||||
// if($password !== 'prototype'){
|
||||
// throw new AccessForbiddenException('Incorrect Password');
|
||||
|
||||
@@ -53,6 +53,8 @@ class DeleteBookingLockLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanDeleteBookingLock
|
||||
|
||||
$password = $request->input('password');
|
||||
if($password !== 'prototype'){
|
||||
throw new AccessForbiddenException('Incorrect Password');
|
||||
|
||||
@@ -13,14 +13,14 @@ use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassTransferPeriodLockRule;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckTransferPeriodLockRuleVariant2DTO;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckTransferPeriodLockRuleVariant2DTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassTransferPeriodLockRule;
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -79,8 +79,10 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
* @param CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule
|
||||
* @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus
|
||||
* @param CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule
|
||||
*/
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, RuleEvaluator $ruleEvaluator, CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor)
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor, RuleEvaluator $ruleEvaluator, CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule)
|
||||
{
|
||||
$this->canUpdateBooking = $canUpdateBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
@@ -91,6 +93,8 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
$this->canPassTransferPeriodLockRule = $canPassTransferPeriodLockRule;
|
||||
$this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassTransferPeriodLockRule = $canPassTransferPeriodLockRule;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,18 +105,18 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
//cief todo: Prototype Period Lock - Starts
|
||||
$reqData['id'] = $request->route('id');
|
||||
$dto = new CheckTransferPeriodLockRuleVariant2DTO($reqData);
|
||||
//cief todo: 110 - Prototype Period Lock - Starts
|
||||
// $reqData['id'] = $request->route('id');
|
||||
// $dto = new CheckTransferPeriodLockRuleVariant2DTO($reqData);
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassTransferPeriodLockRule,
|
||||
], $dto);
|
||||
// $result = $this->ruleEvaluator->evaluate([
|
||||
// $this->canPassTransferPeriodLockRule,
|
||||
// ], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
//cief todo: Prototype Period Lock - Ends
|
||||
// if ($result->failed()) {
|
||||
// throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
// }
|
||||
//cief todo: 110 - Prototype Period Lock - Ends
|
||||
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -7,10 +7,10 @@ use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Jobs\Commands\V2\ProcessPaymentReportV2CommandJob;
|
||||
use App\Classes\Jobs\Commands\V2\ProcessSalesInvoiceReportV2CommandJob;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Imports\Services\AutoCountDataImport;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\CreateChatGPTPromptDTO;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanCreateChatGPTPrompt;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\CreateClaudePromptDTO;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanCreateClaudePrompt;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
|
||||
+5
-3
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\ControllersLogic;
|
||||
namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanCreateBooking;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -50,6 +50,8 @@ class CreateLockLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanCreateLock
|
||||
|
||||
// $password = $request->input('password');
|
||||
// if($password !== 'prototype'){
|
||||
// throw new AccessForbiddenException('Incorrect Password');
|
||||
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\Services\DeletesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\DeletesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanDeleteChatGPTPrompt;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\Services\DeletesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\DeletesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanDeleteClaudePrompt;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
+3
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\ControllersLogic;
|
||||
namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
@@ -49,6 +49,8 @@ class FetchLockLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanFetchLock
|
||||
|
||||
// $this->canFetchBooking->passes();
|
||||
|
||||
// $query = $this->fetchesKeyValuePair->execute(['marking' => $request->route('marking'), 'with_transactions' => true]);
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\ControllersLogic;
|
||||
namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Settings\Services\ListsKeyValuePairs;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\ListsKeyValuePairs;
|
||||
use App\Classes\Modules\ServiceTypes\Standards\Rules\CanListServiceTypes;
|
||||
use App\Http\Resources\LockResource;
|
||||
use ErrorException;
|
||||
@@ -51,6 +51,8 @@ class ListLocksLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanListLocks
|
||||
|
||||
// $this->canListServiceTypes->passes();
|
||||
|
||||
$query = $this->listsKeyValuePairs->execute($this->listsKeyValuePairs->deserializeFilters($request->input('filters')));
|
||||
@@ -4,11 +4,11 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\UpdateChatGPTPromptDTO;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanUpdateChatGPTPrompt;
|
||||
use App\Classes\Modules\Accounts\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Http\Resources\ChatGPTPromptResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -4,11 +4,11 @@ namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\UpdateClaudePromptDTO;
|
||||
use App\Classes\Modules\KeyValuePairs\Standards\Rules\CanUpdateClaudePrompt;
|
||||
use App\Classes\Modules\Accounts\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\FetchesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Http\Resources\ClaudePromptResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
+6
-4
@@ -1,13 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\ControllersLogic;
|
||||
namespace App\Classes\Modules\KeyValuePairs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\ServiceTypes\Standards\Rules\CanUpdateServiceType;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Http\Resources\LockResource;
|
||||
use App\Models\KeyValuePair;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -58,6 +58,8 @@ class UpdateLockLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
// cief todo: 110 - CanUpdateLock
|
||||
|
||||
$key = $request->input('key');
|
||||
$kvp = KeyValuePair::whereNull('owner_type')
|
||||
->whereNull('owner_id')
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\DataTransferObjects;
|
||||
namespace App\Classes\Modules\KeyValuePairs\DataTransferObjects;
|
||||
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
namespace App\Classes\Modules\KeyValuePairs\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
|
||||
use App\Classes\General\Interfaces\KeyValueInterface;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Models\KeyValuePair;
|
||||
|
||||
class CreatesKeyValuePair extends AbstractUpdateRelationshipRecord
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
namespace App\Classes\Modules\KeyValuePairs\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractDeleteRecord;
|
||||
use App\Models\KeyValuePair;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounts\Services;
|
||||
namespace App\Classes\Modules\KeyValuePairs\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractFetchRecord;
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\Services;
|
||||
namespace App\Classes\Modules\KeyValuePairs\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Models\KeyValuePair;
|
||||
|
||||
class UpdatesKeyValuePair extends AbstractUpdateRecord
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
|
||||
use App\Classes\General\Interfaces\KeyValueInterface;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Models\KeyValuePair;
|
||||
|
||||
class CreatesKeyValuePair extends AbstractUpdateRelationshipRecord
|
||||
{
|
||||
/**
|
||||
* @param KeyValueInterface $kv
|
||||
* @param KeyValuePairObject $object
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
|
||||
public function execute(?KeyValueInterface $kv, KeyValuePairObject $object) {
|
||||
$model = new KeyValuePair();
|
||||
$model->key = $object->getKey();
|
||||
$model->value = $object->getValue();
|
||||
|
||||
// Owner-less
|
||||
if (is_null($kv)) {
|
||||
$model->owner_type = null;
|
||||
$model->owner_id = null;
|
||||
$model->save();
|
||||
return $model;
|
||||
}
|
||||
|
||||
return $this->handler($kv->attributesKVP(), $model);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractFetchRecord;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\KeyValuePair;
|
||||
|
||||
class FetchesKeyValuePair extends AbstractFetchRecord
|
||||
{
|
||||
|
||||
/** @var KeyValuePair */
|
||||
private $repository;
|
||||
|
||||
|
||||
/**
|
||||
* FetchesKeyValuePair constructor.
|
||||
* @param KeyValuePair $repository
|
||||
*/
|
||||
public function __construct(KeyValuePair $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Settings\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractListRecord;
|
||||
use App\Models\KeyValuePair;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListsKeyValuePairs extends AbstractListRecord
|
||||
{
|
||||
|
||||
/** @var KeyValuePair */
|
||||
private $repository;
|
||||
|
||||
|
||||
/**
|
||||
* ListsKeyValuePairs constructor.
|
||||
* @param KeyValuePair $repository
|
||||
*/
|
||||
public function __construct(KeyValuePair $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -99,9 +99,9 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
|
||||
]
|
||||
);
|
||||
|
||||
//cief todo: Prototype Period Lock - Starts
|
||||
$this->updateOrCreateKeyValuePair($transaction->owner->booking, KVPKey::BOOKING_IS_LOCKED, 1);
|
||||
//cief todo: Prototype Period Lock - Ends
|
||||
//cief todo: 110 - Prototype Period Lock - Starts
|
||||
// $this->updateOrCreateKeyValuePair($transaction->owner->booking, KVPKey::BOOKING_IS_LOCKED, 1);
|
||||
//cief todo: 110 - Prototype Period Lock - Ends
|
||||
|
||||
// send email to customer
|
||||
// todo: a function to send a proof to the receipiant, they have to give us a email of the receipiant and also need to submiited purchase order
|
||||
|
||||
-3
@@ -24,9 +24,6 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
|
||||
/** @var UpdateRefundTransactionStatusProcessor */
|
||||
private $updateRefundTransactionStatusProcessor;
|
||||
|
||||
/** @var CreateInvoiceTransactionV2Processor */
|
||||
private $createInvoiceTransactionV2Processor;
|
||||
|
||||
/**
|
||||
* UpdateRefundTransactionStatusLogic constructor.
|
||||
* @param UpdateRefundTransactionStatusProcessor $updateRefundTransactionStatusProcessor
|
||||
|
||||
@@ -138,8 +138,8 @@ class CreateInvoiceTransactionV2Processor
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->complete()
|
||||
->first();
|
||||
|
||||
if(!$purchaseOrder && $generateEInvoiceRefund){
|
||||
|
||||
if(!$purchaseOrder){
|
||||
//was use for $generateEInvoiceRefund true
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
|
||||
@@ -16,12 +16,12 @@ use App\Classes\Modules\Vouchers\Services\CreatesVoucher;
|
||||
use App\Classes\Modules\Vouchers\Services\FetchesVoucher;
|
||||
use App\Classes\Modules\Vouchers\Services\UpdatesVoucherCampaign;
|
||||
use App\Classes\Modules\Rewards\Services\CreatesUserReward;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Vouchers\Standards\Rules\CanCreateVoucher;
|
||||
use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherObject;
|
||||
use App\Classes\Modules\Vouchers\DataTransferObjects\CreateVoucherObject;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\Vouchers\DataTransferObjects\VoucherCampaignObject;
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use App\Classes\ValueObjects\Constants\Vouchers;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Classes\Modules\Wallets\Processors;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Models\Wallet;
|
||||
use App\Models\Company;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
@@ -15,10 +15,11 @@ use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Settings\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Settings\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\KeyValuePairs\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\ValueObjects\Constants\KVPKey;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreditWalletProcessor
|
||||
{
|
||||
|
||||
@@ -24,6 +24,16 @@ class KVPKey
|
||||
|
||||
public const BOOKING_EINVOICE_ELIGIBLE = 'BOOKING_EINVOICE_ELIGIBLE';
|
||||
|
||||
public const AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_OFFICIAL_RECEIPT = 'AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_OR';
|
||||
|
||||
public const AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_REFUND = 'AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_RF';
|
||||
|
||||
public const CHATGPT_PROMPT_PREFIX = 'CHATGPT_PROMPT_';
|
||||
public const CLAUDE_PROMPT_PREFIX = 'CLAUDE_PROMPT_';
|
||||
|
||||
public const BOOKING_AMOUNT_UPDATE = 'BOOKING_AMOUNT_UPDATE';
|
||||
|
||||
|
||||
public const BOOKING_IS_LOCKED = 'BOOKING_IS_LOCKED';
|
||||
|
||||
public const UI_SUPPLIER_PAID_CURRENCY_ORDER_TAB_IS_LOCKED = 'UI_SUPPLIER_PAID_CURRENCY_ORDER_TAB_IS_LOCKED';
|
||||
@@ -32,12 +42,4 @@ class KVPKey
|
||||
|
||||
public const UI_PAYMENTS_OPEN_CURRENCY_ORDERS_IS_LOCKED = 'UI_PAYMENTS_OPEN_CURRENCY_ORDERS_IS_LOCKED';
|
||||
|
||||
public const AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_OFFICIAL_RECEIPT = 'AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_OR';
|
||||
|
||||
public const AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_REFUND = 'AUTOCOUNT_DOCNO_SALES_DEPOSIT_BY_WALLET_RF';
|
||||
|
||||
public const BOOKING_AMOUNT_UPDATE = 'BOOKING_AMOUNT_UPDATE';
|
||||
|
||||
public const CHATGPT_PROMPT_PREFIX = 'CHATGPT_PROMPT_';
|
||||
public const CLAUDE_PROMPT_PREFIX = 'CLAUDE_PROMPT_';
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use Illuminate\Http\Request;
|
||||
|
||||
class CreateSystemUserController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CreateSystemUserLogic $logic
|
||||
|
||||
@@ -3,35 +3,21 @@
|
||||
namespace App\Http\Controllers\Affiliate;
|
||||
|
||||
use App\Classes\Modules\Affiliate\ControllersLogic\CreateAffiliateLogic;
|
||||
use App\Http\Requests\CreateAffiliateRequest;
|
||||
use App\Models\Affiliate;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateAffiliateController
|
||||
{
|
||||
/**
|
||||
* @param CreateAffiliateRequest $request
|
||||
* @param Request $request
|
||||
* @param CreateAffiliateLogic $logic
|
||||
* @return JsonResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create(CreateAffiliateRequest $request, CreateAffiliateLogic $logic): JsonResponse {
|
||||
$this->authorize('create', Affiliate::class);
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize a given action for the current user.
|
||||
*
|
||||
* @param mixed $ability
|
||||
* @param mixed|array $arguments
|
||||
* @return \Illuminate\Auth\Access\Response
|
||||
*
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function authorize($ability, $arguments = [])
|
||||
public function create(Request $request, CreateAffiliateLogic $logic): JsonResponse
|
||||
{
|
||||
return app(\Illuminate\Contracts\Auth\Access\Gate::class)->authorize($ability, $arguments);
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
namespace App\Http\Controllers\KeyValuePairs;
|
||||
|
||||
use App\Classes\Modules\Settings\ControllersLogic\CreateLockLogic;
|
||||
use App\Classes\Modules\KeyValuePairs\ControllersLogic\CreateLockLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
namespace App\Http\Controllers\KeyValuePairs;
|
||||
|
||||
use App\Classes\Modules\Settings\ControllersLogic\FetchLockLogic;
|
||||
use App\Classes\Modules\KeyValuePairs\ControllersLogic\FetchLockLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
namespace App\Http\Controllers\KeyValuePairs;
|
||||
|
||||
use App\Classes\Modules\Settings\ControllersLogic\ListLocksLogic;
|
||||
use App\Classes\Modules\KeyValuePairs\ControllersLogic\ListLocksLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
namespace App\Http\Controllers\KeyValuePairs;
|
||||
|
||||
use App\Classes\Modules\Settings\ControllersLogic\UpdateLockLogic;
|
||||
use App\Classes\Modules\KeyValuePairs\ControllersLogic\UpdateLockLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Classes\Modules\Rules\ControllersLogic\CheckPurchaseOrderRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckTransferRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckTransferPeriodLockRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckEInvoiceAmountLimitLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckTransferPeriodLockRuleLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -56,4 +57,13 @@ class CheckRuleController
|
||||
public function checkEInvoiceAmountLimitRule(Request $request, CheckEInvoiceAmountLimitLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CheckTransferPeriodLockRuleLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkTransferPeriodLockRule(Request $request, CheckTransferPeriodLockRuleLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ class CreateAffiliateRequest extends FormRequest
|
||||
'min:3',
|
||||
'max:255',
|
||||
'regex:/^[a-zA-Z0-9_-]+$/',
|
||||
'unique:affiliates,code,NULL,id,deleted_at,NULL'
|
||||
],
|
||||
'campaign_name' => 'required|string|max:255',
|
||||
'campaign_description' => 'nullable|string|max:65535',
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -205,7 +205,9 @@
|
||||
|
||||
},
|
||||
submitForm(){
|
||||
this.step === 2 ? this.submit(this.route('api.account.registration.register'), 'post', 'registrationSection', false, false) : this.changeStep('next');
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const tracking = urlParams.get('tracking');
|
||||
this.step === 2 ? this.submit(this.route('api.account.registration.register') + (tracking ? '?tracking=' + tracking : ''), 'post', 'registrationSection', false, false) : this.changeStep('next');
|
||||
},
|
||||
successHandler(response){
|
||||
// fire to gtag manager for fb pixel tracking: CompleteRegistration
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
|
||||
<!-- Approve and Edit Purchase Order -->
|
||||
<div class="row" v-if="submitted">
|
||||
<div class="col-12 col-md-5 pr-md-0" v-if="submitted && data.status !== 3">
|
||||
<div class="col-12 col-md-5 pr-md-0" v-if="submitted">
|
||||
<div class="row m-b-15" v-if="($store.getters.isAdmin && data.purchase_order.status === 1) || ($store.getters.isCustomer && data.purchase_order.status === 1 && $store.getters.getCompanyId === 199)" >
|
||||
<div class="col">
|
||||
<button class="btn btn-sm btn-block btn-success b-rad-none" :disabled="poProcessing" @click="handleRepprove()">Approve Purchase Order</button>
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="row parentContainer">
|
||||
<div class="col">
|
||||
<!-- cief todo: Prototype Period Lock - Starts -->
|
||||
<button v-if="booking && !locked && lockInitialized && $store.getters.isAdmin" @click="lock">
|
||||
<!-- cief todo: 110 - Prototype Period Lock - Starts -->
|
||||
<!-- <button v-if="booking && !locked && lockInitialized && $store.getters.isAdmin" @click="lock">
|
||||
🔒 Lock Page
|
||||
</button>
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
:password="''"
|
||||
v-on:lock="lock"
|
||||
v-on:initializeLock="initializeLock">
|
||||
</page-lock>
|
||||
<!-- cief todo: Prototype Period Lock - Ends -->
|
||||
</page-lock> -->
|
||||
<!-- cief todo: 110 - Prototype Period Lock - Ends -->
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row" v-show="!isLoading" v-if="booking">
|
||||
<div class="col-md col-sm-12 m-b-20">
|
||||
|
||||
@@ -42,6 +42,28 @@
|
||||
</modal-form-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col p-r-0">
|
||||
<div class="form-group no-margin form-group-default b-rad-none">
|
||||
<label class="text-primary">Search</label>
|
||||
<input type="text" class="form-control" v-model="searchTerm" @keyup.enter="search" placeholder="Search by campaign name, code, or description"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0 p-r-0">
|
||||
<div class="btn btn-primary b-rad-none" @click="search">
|
||||
<i class="fa fa-search lh-40"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="btn btn-secondary b-rad-none" @click="reset">
|
||||
<i class="fa fa-remove lh-40"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-10 b-b p-b-5" style="border-color: #e0e0e0 !important;">
|
||||
<div class="col-2">
|
||||
<div class="font-heading all-caps fs-9 muted">Campaign</div>
|
||||
@@ -71,7 +93,7 @@
|
||||
</div>
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<list-component section="affiliatesSection" :endpoint="route('api.affiliate.list')" :key="refreshKey">
|
||||
<list-component section="affiliatesSection" :endpoint="route('api.affiliate.list')" :key="refreshKey" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<affiliate-single-item-component section="affiliatesSection" :data="data"></affiliate-single-item-component>
|
||||
</template>
|
||||
@@ -89,12 +111,27 @@
|
||||
data() {
|
||||
return {
|
||||
refreshKey: 1,
|
||||
searchTerm: '',
|
||||
options: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshAffiliateCodes() {
|
||||
this.refreshKey++;
|
||||
},
|
||||
search() {
|
||||
if (this.searchTerm && this.searchTerm.trim()) {
|
||||
this.options['affiliate_search'] = this.searchTerm.trim();
|
||||
} else {
|
||||
delete this.options['affiliate_search'];
|
||||
}
|
||||
this.refreshKey++;
|
||||
},
|
||||
reset() {
|
||||
this.searchTerm = '';
|
||||
delete this.options['affiliate_search'];
|
||||
this.refreshKey++;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -195,7 +195,21 @@
|
||||
errorHandler(error) {
|
||||
// Don't reload the list on error - just handle the error message
|
||||
this.isLoading = false;
|
||||
this.errorMessageHandler(error);
|
||||
|
||||
// Parse error message properly
|
||||
let errorMessage = error.message || error;
|
||||
|
||||
// If error.message is a JSON string, parse it
|
||||
if (typeof errorMessage === 'string') {
|
||||
try {
|
||||
const parsed = JSON.parse(errorMessage);
|
||||
errorMessage = parsed.message || errorMessage;
|
||||
} catch (e) {
|
||||
// If parsing fails, use the message as-is
|
||||
}
|
||||
}
|
||||
|
||||
this.errorMessageHandler(errorMessage);
|
||||
},
|
||||
resetForm() {
|
||||
if (this.$v) {
|
||||
@@ -215,7 +229,7 @@
|
||||
if (!this.validate()) {
|
||||
return;
|
||||
}
|
||||
const url = this.parameters.id
|
||||
const url = this.parameters.id
|
||||
? this.route('api.affiliate.update', this.parameters.id)
|
||||
: this.route('api.affiliate.create');
|
||||
const method = this.parameters.id ? 'put' : 'post';
|
||||
|
||||
@@ -0,0 +1,925 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>1688支付替代方案 - 马币直付 | CIEF Source 官方授权代付服务</title>
|
||||
<meta name="title" content="1688支付替代方案 - 马币直付 | CIEF Source 官方授权代付服务">
|
||||
<meta name="description" content="无需开通支付宝,无需处理外汇。用马币(MYR)完成人民币代付1688订单,订单状态秒级同步,发票合规可对账。官方授权,安全合规,10,000+成功代付案例。">
|
||||
<meta name="keywords" content="1688支付,1688代付,马币支付1688,1688支付替代方案,支付宝替代,1688人民币代付,马来西亚1688支付,CIEF Source,1688订单支付,跨境支付">
|
||||
<meta name="author" content="CIEF Source">
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="language" content="Chinese">
|
||||
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href="{{ url('/1688-payment-alternative-cn') }}">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{ url('/1688-payment-alternative-cn') }}">
|
||||
<meta property="og:title" content="1688支付替代方案 - 马币直付 | CIEF Source">
|
||||
<meta property="og:description" content="无需开通支付宝,无需处理外汇。用马币完成人民币代付1688订单,订单状态秒级同步,发票合规可对账。">
|
||||
<meta property="og:locale" content="zh_CN">
|
||||
<meta property="og:site_name" content="CIEF Source">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:url" content="{{ url('/1688-payment-alternative-cn') }}">
|
||||
<meta name="twitter:title" content="1688支付替代方案 - 马币直付 | CIEF Source">
|
||||
<meta name="twitter:description" content="无需开通支付宝,无需处理外汇。用马币完成人民币代付1688订单,订单状态秒级同步,发票合规可对账。">
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('images/favicon/apple-touch-icon.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ asset('images/favicon/favicon-32x32.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ asset('images/favicon/favicon-16x16.png') }}">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
|
||||
<!-- Preconnect for Performance -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
|
||||
|
||||
<!-- Structured Data (JSON-LD) -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"name": "1688支付替代方案",
|
||||
"description": "无需开通支付宝,无需处理外汇。用马币(MYR)完成人民币代付1688订单,订单状态秒级同步,发票合规可对账。",
|
||||
"provider": {
|
||||
"@type": "Organization",
|
||||
"name": "CIEF Source",
|
||||
"url": "{{ url('/') }}"
|
||||
},
|
||||
"areaServed": {
|
||||
"@type": "Country",
|
||||
"name": "Malaysia"
|
||||
},
|
||||
"serviceType": "跨境支付服务"
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [{
|
||||
"@type": "Question",
|
||||
"name": "代付安全吗?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "CIEF 通过阿里官方 API 进行代付,支付记录与订单回执全链路可追踪。"
|
||||
}
|
||||
}, {
|
||||
"@type": "Question",
|
||||
"name": "汇率如何计算?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "系统每日更新官方汇率;确认前可在界面预览最终金额。"
|
||||
}
|
||||
}, {
|
||||
"@type": "Question",
|
||||
"name": "是否提供马来西亚发票?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "支持开具马来西亚正规发票,便于会计与审计对账。"
|
||||
}
|
||||
}, {
|
||||
"@type": "Question",
|
||||
"name": "是否有最低代付金额?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "无最低限制,小至单笔订单亦可受理。"
|
||||
}
|
||||
}, {
|
||||
"@type": "Question",
|
||||
"name": "代付后如何跟进发货?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "订单与发货信息会回传至 CIEF Source,你可在同一系统继续安排清关与配送。"
|
||||
}
|
||||
}]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* === CSS Variables === */
|
||||
:root {
|
||||
--primary: #22c55e;
|
||||
--secondary: #38bdf8;
|
||||
--dark: #0f172a;
|
||||
--dark-card: #1e293b;
|
||||
--text: #e2e8f0;
|
||||
--text-muted: #94a3b8;
|
||||
--border: #334155;
|
||||
--radius: 16px;
|
||||
}
|
||||
|
||||
/* === Reset & Base === */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img { max-width: 100%; height: auto; }
|
||||
a { text-decoration: none; color: inherit; }
|
||||
|
||||
/* === Typography === */
|
||||
.heading-xl {
|
||||
font-size: clamp(32px, 5vw, 52px);
|
||||
line-height: 1.2;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.heading-lg {
|
||||
font-size: clamp(24px, 4vw, 36px);
|
||||
line-height: 1.3;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.heading-md {
|
||||
font-size: clamp(20px, 3vw, 28px);
|
||||
line-height: 1.4;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.text-lg {
|
||||
font-size: clamp(16px, 2.5vw, 20px);
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: var(--text-muted);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* === Buttons === */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 14px 28px;
|
||||
border-radius: 100px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--primary), #16a34a);
|
||||
color: #0a2e19;
|
||||
box-shadow: 0 8px 20px rgba(34, 197, 94, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 12px 28px rgba(34, 197, 94, 0.4);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: rgba(148, 163, 184, 0.1);
|
||||
border-color: var(--border);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: rgba(148, 163, 184, 0.15);
|
||||
border-color: #475569;
|
||||
}
|
||||
|
||||
/* === Badges & Pills === */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
border: 1px solid rgba(34, 197, 94, 0.3);
|
||||
border-radius: 100px;
|
||||
color: #86efac;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pill {
|
||||
display: inline-block;
|
||||
padding: 6px 14px;
|
||||
background: rgba(56, 189, 248, 0.1);
|
||||
border: 1px solid rgba(56, 189, 248, 0.3);
|
||||
border-radius: 100px;
|
||||
color: #7dd3fc;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* === Cards === */
|
||||
.card {
|
||||
background: linear-gradient(180deg, rgba(30, 41, 59, 0.8), rgba(15, 23, 42, 0.6));
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 24px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: #475569;
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* === Grid System === */
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.grid-2 { grid-template-columns: 1fr; }
|
||||
.grid-3 { grid-template-columns: 1fr; }
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.grid-2 { grid-template-columns: repeat(2, 1fr); }
|
||||
.grid-3 { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
.grid-3 { grid-template-columns: repeat(3, 1fr); }
|
||||
}
|
||||
|
||||
/* === Sections === */
|
||||
.section {
|
||||
padding: 80px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-sm { padding: 50px 0; }
|
||||
|
||||
/* === Hero Section === */
|
||||
.hero {
|
||||
padding: 100px 0 80px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -20%;
|
||||
right: -10%;
|
||||
width: 800px;
|
||||
height: 800px;
|
||||
background: radial-gradient(circle, rgba(34, 197, 94, 0.15), transparent 70%);
|
||||
filter: blur(60px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -20%;
|
||||
left: -10%;
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, rgba(56, 189, 248, 0.12), transparent 70%);
|
||||
filter: blur(50px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
.hero-grid { grid-template-columns: 1.2fr 1fr; }
|
||||
}
|
||||
|
||||
/* === Stats === */
|
||||
.stats {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
padding: 10px 16px;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
border: 1px dashed rgba(129, 140, 248, 0.3);
|
||||
border-radius: 12px;
|
||||
color: #a5b4fc;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* === Feature Items === */
|
||||
.feature-item {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
flex-shrink: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(56, 189, 248, 0.1);
|
||||
border: 1px solid rgba(56, 189, 248, 0.3);
|
||||
border-radius: 12px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
/* === Flow Diagram === */
|
||||
.flow-card {
|
||||
background: rgba(15, 23, 42, 0.6);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.flow-step {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
padding: 16px;
|
||||
background: rgba(30, 41, 59, 0.5);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.flow-step:last-child { margin-bottom: 0; }
|
||||
|
||||
.step-number {
|
||||
flex-shrink: 0;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(56, 189, 248, 0.15);
|
||||
border: 1px solid rgba(56, 189, 248, 0.4);
|
||||
border-radius: 10px;
|
||||
color: #7dd3fc;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.flow-arrow {
|
||||
text-align: center;
|
||||
color: var(--secondary);
|
||||
font-size: 24px;
|
||||
margin: -6px 0;
|
||||
}
|
||||
|
||||
/* === Diagram Box === */
|
||||
.diagram-box {
|
||||
background: linear-gradient(180deg, rgba(30, 41, 59, 0.7), rgba(15, 23, 42, 0.5));
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 24px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.node {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 16px;
|
||||
background: rgba(30, 41, 59, 0.5);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.node:last-child { margin-bottom: 0; }
|
||||
|
||||
.node-badge {
|
||||
padding: 4px 12px;
|
||||
background: rgba(34, 197, 94, 0.15);
|
||||
border: 1px solid rgba(34, 197, 94, 0.3);
|
||||
border-radius: 8px;
|
||||
color: #86efac;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* === Table === */
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: rgba(30, 41, 59, 0.6);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
table th {
|
||||
background: rgba(15, 23, 42, 0.8);
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table tr:hover {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
}
|
||||
|
||||
/* === FAQ === */
|
||||
.faq-item {
|
||||
background: rgba(30, 41, 59, 0.6);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.faq-question span {
|
||||
font-size: 20px;
|
||||
color: var(--secondary);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.faq-item.active .faq-question span {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
margin-top: 12px;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.faq-item.active .faq-answer {
|
||||
max-height: 500px;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
/* === CTA Banner === */
|
||||
.cta-banner {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(56, 189, 248, 0.1));
|
||||
border: 1px solid rgba(34, 197, 94, 0.3);
|
||||
border-radius: 24px;
|
||||
padding: 50px 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
/* === Footer === */
|
||||
.footer {
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid var(--border);
|
||||
color: var(--text-muted);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* === Utilities === */
|
||||
.text-center { text-align: center; }
|
||||
.mb-0 { margin-bottom: 0; }
|
||||
.mb-1 { margin-bottom: 8px; }
|
||||
.mb-2 { margin-bottom: 16px; }
|
||||
.mb-3 { margin-bottom: 24px; }
|
||||
.mt-2 { margin-top: 16px; }
|
||||
.mt-3 { margin-top: 24px; }
|
||||
.gap-2 { gap: 16px; }
|
||||
.flex { display: flex; }
|
||||
.flex-wrap { flex-wrap: wrap; }
|
||||
.highlight { color: var(--primary); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero">
|
||||
<div class="container hero-content">
|
||||
<div class="hero-grid">
|
||||
<div>
|
||||
<span class="badge">✓ 官方授权 · 安全合规 · 马币直付</span>
|
||||
<h1 class="heading-xl">
|
||||
无法支付 1688 订单?<br>
|
||||
用 <span class="highlight">CIEF 支付替代方案</span> 一键搞定
|
||||
</h1>
|
||||
<p class="text-lg">
|
||||
无需开通支付宝,无需处理外汇。用马币(MYR)完成人民币代付,订单状态秒级同步,发票合规可对账。
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2 mt-3">
|
||||
<a href="#start" class="btn btn-primary">
|
||||
开始代付 1688 订单
|
||||
</a>
|
||||
<a href="https://wa.me/60123456789" class="btn btn-secondary" target="_blank" rel="noopener">
|
||||
WhatsApp 咨询
|
||||
</a>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<div class="stat-item">🎯 10,000+ 成功代付</div>
|
||||
<div class="stat-item">⚡ API 直连 · 可追踪</div>
|
||||
<div class="stat-item">🧾 马来西亚正规发票</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diagram-box">
|
||||
<div class="node">
|
||||
<strong>买家(你)</strong>
|
||||
<span class="node-badge">MYR 付款</span>
|
||||
</div>
|
||||
<div class="flow-arrow">⇣</div>
|
||||
<div class="node">
|
||||
<strong>CIEF 系统</strong>
|
||||
<span class="node-badge">API 处理</span>
|
||||
</div>
|
||||
<div class="flow-arrow">⇣</div>
|
||||
<div class="node">
|
||||
<strong>1688 卖家</strong>
|
||||
<span class="node-badge">RMB 收款</span>
|
||||
</div>
|
||||
<div class="flow-arrow">⇣</div>
|
||||
<div class="node">
|
||||
<strong>物流清关</strong>
|
||||
<span class="node-badge">一条龙</span>
|
||||
</div>
|
||||
<p class="text-muted" style="margin-top: 16px; font-size: 13px;">
|
||||
💡 提示:可在 CIEF Source 内直接跟踪订单状态与物流进度
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Pain Points -->
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<span class="pill">常见难题</span>
|
||||
<h2 class="heading-lg">你是否也遇到这些支付障碍?</h2>
|
||||
<p class="text-muted mb-3">跨境采购最常见的痛点,我们都已替客户解决过:</p>
|
||||
|
||||
<div class="grid grid-2">
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🚫</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">无法开通/使用支付宝</h3>
|
||||
<p class="text-muted">没有中国手机号或资质,支付宝难以落地。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🏢</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">公司账户难以对外汇款</h3>
|
||||
<p class="text-muted">银行外汇手续复杂、到账慢、沟通成本高。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">⏱️</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">时效 & 可追踪性差</h3>
|
||||
<p class="text-muted">传统"找人代付"风险高、无法系统化追踪。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🧾</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">发票与对账不合规</h3>
|
||||
<p class="text-muted">无法拿到马来西亚发票,财务对账困难。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Solution -->
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<span class="pill">解决方案</span>
|
||||
<h2 class="heading-lg">官方授权 · 安全合规的 1688 支付替代方案</h2>
|
||||
<p class="text-muted mb-3">
|
||||
CIEF 作为 1688 官方合作方,支持你用马币完成人民币代付,付款即刻同步订单状态,并可无缝衔接采购、清关与配送。
|
||||
</p>
|
||||
|
||||
<div class="grid grid-2">
|
||||
<div class="flow-card">
|
||||
<div class="flow-step">
|
||||
<div class="step-number">1</div>
|
||||
<div>
|
||||
<strong>提交 1688 订单链接</strong>
|
||||
<p class="text-muted mb-0">在 CIEF Source 粘贴链接或上传截图,便可开始。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="step-number">2</div>
|
||||
<div>
|
||||
<strong>确认金额与汇率</strong>
|
||||
<p class="text-muted mb-0">系统显示代付金额(含当日汇率),确认无误即下一步。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="step-number">3</div>
|
||||
<div>
|
||||
<strong>用马币付款给 CIEF</strong>
|
||||
<p class="text-muted mb-0">支持转账/FPX 等方式,企业可走公司账。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="step-number">4</div>
|
||||
<div>
|
||||
<strong>API 代你支付卖家</strong>
|
||||
<p class="text-muted mb-0">Ali 官方 API 直连,安全稳定可追踪。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-step">
|
||||
<div class="step-number">5</div>
|
||||
<div>
|
||||
<strong>订单与物流状态同步</strong>
|
||||
<p class="text-muted mb-0">代付完成后,订单状态与发货信息自动回传。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">💵</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">马币直付</h3>
|
||||
<p class="text-muted mb-0">无需人民币账户,无需外汇繁琐流程。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🔒</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">官方 API</h3>
|
||||
<p class="text-muted mb-0">阿里官方接口,支付与回执全链路记录。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">⚡</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">秒级入账</h3>
|
||||
<p class="text-muted mb-0">确认后快速代付,缩短采购周期。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">🧾</div>
|
||||
<div>
|
||||
<h3 class="heading-md mb-1">马来西亚发票</h3>
|
||||
<p class="text-muted mb-0">开具正规发票,方便会计与审计对账。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2 mt-3">
|
||||
<a href="#start" class="btn btn-primary">
|
||||
现在用马币代付
|
||||
</a>
|
||||
<a href="https://wa.me/60123456789" class="btn btn-secondary" target="_blank" rel="noopener">
|
||||
咨询客服
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Comparison Table -->
|
||||
<section class="section-sm">
|
||||
<div class="container">
|
||||
<span class="pill">为什么选我们</span>
|
||||
<h2 class="heading-lg">一眼看懂:传统方式 vs CIEF 方案</h2>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>项目</th>
|
||||
<th>传统方式</th>
|
||||
<th>CIEF 支付替代方案</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>开通支付宝</td>
|
||||
<td>需中国手机号/身份证,流程复杂</td>
|
||||
<td><strong style="color: var(--primary);">无需</strong>,直接用马币支付</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>外汇手续</td>
|
||||
<td>流程长、沟通成本高</td>
|
||||
<td><strong style="color: var(--primary);">省去外汇步骤</strong>,企业可走公司账</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>安全性</td>
|
||||
<td>找人代付,风险与纠纷高</td>
|
||||
<td><strong style="color: var(--primary);">官方 API</strong> 直连,支付有据可查</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>订单追踪</td>
|
||||
<td>支付后信息割裂,不易追踪</td>
|
||||
<td><strong style="color: var(--primary);">系统实时回传</strong> 下单/发货状态</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>发票对账</td>
|
||||
<td>无法取得本地发票</td>
|
||||
<td><strong style="color: var(--primary);">马来西亚正规发票</strong>,合规对账</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Social Proof -->
|
||||
<section class="section-sm">
|
||||
<div class="container">
|
||||
<div class="grid grid-3">
|
||||
<div class="card text-center">
|
||||
<h3 class="heading-md">1688 官方合作伙伴</h3>
|
||||
<p class="text-muted mb-0">长期技术与业务合作,可信赖的跨境解决方案。</p>
|
||||
</div>
|
||||
|
||||
<div class="card text-center">
|
||||
<h3 class="heading-md">10,000+ 成功代付</h3>
|
||||
<p class="text-muted mb-0">覆盖多行业客户,口碑沉淀与流程完善。</p>
|
||||
</div>
|
||||
|
||||
<div class="card text-center">
|
||||
<h3 class="heading-md">端到端一条龙</h3>
|
||||
<p class="text-muted mb-0">采购、代付、清关、配送与对账,全流程打通。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FAQ -->
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<span class="pill">FAQ</span>
|
||||
<h2 class="heading-lg">常见问题</h2>
|
||||
|
||||
<div class="grid">
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" onclick="this.parentElement.classList.toggle('active')">
|
||||
代付安全吗?
|
||||
<span>+</span>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
CIEF 通过阿里官方 API 进行代付,支付记录与订单回执全链路可追踪。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" onclick="this.parentElement.classList.toggle('active')">
|
||||
汇率如何计算?
|
||||
<span>+</span>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
系统每日更新官方汇率;确认前可在界面预览最终金额。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" onclick="this.parentElement.classList.toggle('active')">
|
||||
是否提供马来西亚发票?
|
||||
<span>+</span>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
支持开具马来西亚正规发票,便于会计与审计对账。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" onclick="this.parentElement.classList.toggle('active')">
|
||||
是否有最低代付金额?
|
||||
<span>+</span>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
无最低限制,小至单笔订单亦可受理。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question" onclick="this.parentElement.classList.toggle('active')">
|
||||
代付后如何跟进发货?
|
||||
<span>+</span>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
订单与发货信息会回传至 CIEF Source,你可在同一系统继续安排清关与配送。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Banner -->
|
||||
<section class="section-sm">
|
||||
<div class="container">
|
||||
<div class="cta-banner">
|
||||
<h2 class="heading-lg mb-2">让采购更简单、安全、合规</h2>
|
||||
<p class="text-lg mb-0">现在就用马币为你的 1688 订单代付,并在同一平台完成清关与对账。</p>
|
||||
<div class="cta-buttons">
|
||||
<a href="#start" class="btn btn-primary">开始使用</a>
|
||||
<a href="https://wa.me/60123456789" class="btn btn-secondary" target="_blank" rel="noopener">联系客服</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p>© {{ date('Y') }} CIEF Source. All rights reserved.</p>
|
||||
<p>1688 官方授权支付替代方案服务商</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
+1257
File diff suppressed because it is too large
Load Diff
+1288
File diff suppressed because it is too large
Load Diff
+1288
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -78,6 +78,29 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-5" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col bg-master-light tabButton" tab-name="affiliateSettings">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto p-t-10 p-b-10 b-r b-grey">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="35" height="35"
|
||||
viewBox="0 0 172 172"
|
||||
style=" fill:#000000;"><defs><linearGradient x1="86" y1="28.55469" x2="86" y2="143.10938" gradientUnits="userSpaceOnUse" id="color-4_affiliate_gr4"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g><path d="M86,21.5c-35.56369,0 -64.5,28.93631 -64.5,64.5c0,35.56369 28.93631,64.5 64.5,64.5c35.56369,0 64.5,-28.93631 64.5,-64.5c0,-35.56369 -28.93631,-64.5 -64.5,-64.5zM86,32.25c29.63631,0 53.75,24.11369 53.75,53.75c0,29.63631 -24.11369,53.75 -53.75,53.75c-29.63631,0 -53.75,-24.11369 -53.75,-53.75c0,-29.63631 24.11369,-53.75 53.75,-53.75zM86,48.375c-20.81887,0 -37.625,16.80613 -37.625,37.625c0,20.81887 16.80613,37.625 37.625,37.625c20.81887,0 37.625,-16.80613 37.625,-37.625c0,-20.81887 -16.80613,-37.625 -37.625,-37.625zM86,59.125c14.81887,0 26.875,12.05613 26.875,26.875c0,14.81887 -12.05613,26.875 -26.875,26.875c-14.81887,0 -26.875,-12.05613 -26.875,-26.875c0,-14.81887 12.05613,-26.875 26.875,-26.875z" fill="url(#color-4_affiliate_gr4)"></path></g></g></svg>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="fs-12 m-t-5 all-caps m-b-5">Affiliate</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="$store.getters.isSuperAdmin">
|
||||
<div class="row m-b-5">
|
||||
<div class="col">
|
||||
@@ -248,10 +271,31 @@
|
||||
<div class="col bg-master-light tabButton" tab-name="aiPrompts">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto p-t-10 p-b-10 b-r b-grey">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="35" height="35"
|
||||
viewBox="0 0 172 172"
|
||||
style=" fill:#000000;"><defs><linearGradient x1="99.4375" y1="43.33594" x2="99.4375" y2="60.14625" gradientUnits="userSpaceOnUse" id="color-1_43971_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="106.15625" y1="26.875" x2="106.15625" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-2_43971_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="83.3125" y1="26.875" x2="83.3125" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-3_43971_gr3"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="73.90625" y1="26.875" x2="73.90625" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-4_43971_gr4"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="51.0625" y1="26.875" x2="51.0625" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-5_43971_gr5"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="51.0625" y1="26.875" x2="51.0625" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-6_43971_gr6"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="45.6875" y1="26.875" x2="45.6875" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-7_43971_gr7"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="43" y1="26.875" x2="43" y2="146.16775" gradientUnits="userSpaceOnUse" id="color-8_43971_gr8"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g><path d="M112.875,59.125h-26.875c-1.4835,0 -2.6875,-1.204 -2.6875,-2.6875v-10.75c0,-1.4835 1.204,-2.6875 2.6875,-2.6875h26.875c1.4835,0 2.6875,1.204 2.6875,2.6875v10.75c0,1.4835 -1.204,2.6875 -2.6875,2.6875z" fill="url(#color-1_43971_gr1)"></path><path d="M155.875,96.75c0,-7.97381 -5.82381,-14.59581 -13.4375,-15.88313v-18.82325c0,-2.08819 -1.16906,-3.94525 -3.05031,-4.85094c-1.88125,-0.90031 -4.06081,-0.65575 -5.69481,0.64769l-21.48925,17.18925c-0.08062,0.0645 -0.13975,0.14781 -0.21769,0.21769h-31.36044c-7.40944,0 -13.4375,6.02806 -13.4375,13.4375h-5.375c-2.96431,0 -5.375,2.41069 -5.375,5.375v5.375c0,2.96431 2.41069,5.375 5.375,5.375h5.375c0,7.40944 6.02806,13.4375 13.4375,13.4375v16.125c0,5.92863 4.82138,10.75 10.75,10.75c5.92863,0 10.75,-4.82137 10.75,-10.75v-16.125h9.86044c0.07794,0.06988 0.13706,0.15319 0.22038,0.22037l21.48656,17.18925c0.98094,0.78475 2.16075,1.18519 3.35131,1.18519c0.79281,0 1.59369,-0.17738 2.3435,-0.5375c1.88125,-0.903 3.05031,-2.76275 3.05031,-4.84825v-18.82325c7.61369,-1.28731 13.4375,-7.90931 13.4375,-15.88312zM61.8125,99.4375v-5.375h5.375v5.375zM96.75,134.375c0,2.96431 -2.41069,5.375 -5.375,5.375c-2.96431,0 -5.375,-2.41069 -5.375,-5.375v-16.125h10.75zM80.625,112.875c-4.44513,0 -8.0625,-3.61738 -8.0625,-8.0625v-16.125c0,-4.44513 3.61737,-8.0625 8.0625,-8.0625h29.5625v32.25h-8.0625zM137.05175,131.46175l-21.48925,-17.19462v-35.04231l10.75,-8.59194v26.11713h5.375v-30.41175l5.375,-4.29462l0.00538,69.42887c0,0 -0.00538,-0.00269 -0.01613,-0.01075zM142.4375,107.11837v-20.73675c4.6225,1.20131 8.0625,5.375 8.0625,10.36838c0,4.99337 -3.44,9.16706 -8.0625,10.36838z" fill="url(#color-2_43971_gr2)"></path><path d="M77.9375,91.375v5.375h5.375v-5.375h5.375v-5.375h-5.375c-2.96431,0 -5.375,2.41069 -5.375,5.375z" fill="url(#color-3_43971_gr3)"></path><path d="M21.5,107.5v-67.1875c0,-4.44512 3.61737,-8.0625 8.0625,-8.0625h88.6875c4.44512,0 8.0625,3.61738 8.0625,8.0625v10.75h5.375v-10.75c0,-7.40944 -6.02806,-13.4375 -13.4375,-13.4375h-88.6875c-7.40944,0 -13.4375,6.02806 -13.4375,13.4375v67.1875c0,7.40944 6.02806,13.4375 13.4375,13.4375h32.25v-5.375h-32.25c-4.44513,0 -8.0625,-3.61737 -8.0625,-8.0625z" fill="url(#color-4_43971_gr4)"></path><path d="M32.25,43h37.625v5.375h-37.625z" fill="url(#color-5_43971_gr5)"></path><path d="M32.25,53.75h37.625v5.375h-37.625z" fill="url(#color-6_43971_gr6)"></path><path d="M32.25,64.5h26.875v5.375h-26.875z" fill="url(#color-7_43971_gr7)"></path><path d="M32.25,75.25h21.5v5.375h-21.5z" fill="url(#color-8_43971_gr8)"></path></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" viewBox="0 0 172 172">
|
||||
<defs>
|
||||
<linearGradient id="g1" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#4ec9ff"/>
|
||||
<stop offset="100%" stop-color="#2bffe6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g2" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#009add"/>
|
||||
<stop offset="100%" stop-color="#00baa4"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Chat bubble -->
|
||||
<rect x="20" y="28" rx="10" ry="10" width="110" height="78" fill="url(#g2)"/>
|
||||
<polygon points="50,106 65,106 55,126" fill="url(#g2)"/>
|
||||
|
||||
<!-- Prompt lines -->
|
||||
<rect x="35" y="45" width="70" height="8" rx="4" fill="url(#g1)"/>
|
||||
<rect x="35" y="60" width="55" height="8" rx="4" fill="url(#g1)"/>
|
||||
<rect x="35" y="75" width="40" height="8" rx="4" fill="url(#g1)"/>
|
||||
|
||||
<!-- AI Spark -->
|
||||
<polygon points="115,40 120,55 135,60 120,65 115,80 110,65 95,60 110,55"
|
||||
fill="url(#g1)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="fs-12 m-t-5 all-caps m-b-5">AI Prompts</div>
|
||||
|
||||
@@ -122,11 +122,13 @@
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component key="lock-1" section="lockPaidBillGroup" :endpoint="route('api.setting.list.lock')" :options="{'key_value_pair_in': ['UI_SUPPLIER_PAID_CURRENCY_ORDER_TAB_IS_LOCKED']}" style="min-height: 50px;width:100%">
|
||||
<!-- cief todo: 110 - Prototype Period Lock - Starts -->
|
||||
<!-- <list-component key="lock-1" section="lockPaidBillGroup" :endpoint="route('api.setting.list.lock')" :options="{'key_value_pair_in': ['UI_SUPPLIER_PAID_CURRENCY_ORDER_TAB_IS_LOCKED']}" style="min-height: 50px;width:100%">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<component-lock section="lockPaidBillGroup" :data="data"></component-lock>
|
||||
</template>
|
||||
</list-component>
|
||||
</list-component> -->
|
||||
<!-- cief todo: 110 - Prototype Period Lock - Ends -->
|
||||
<bill-group-list-section-component section="paidBillGroupList"></bill-group-list-section-component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -82,6 +82,10 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
|
||||
|
||||
require __DIR__ . '/key_value_pair.php';
|
||||
|
||||
require __DIR__ . '/setting.php';
|
||||
|
||||
require __DIR__ . '/affiliate.php';
|
||||
|
||||
// require __DIR__ . '/rate.php';
|
||||
// require __DIR__ . '/receipt.php';
|
||||
});
|
||||
|
||||
@@ -6,6 +6,8 @@ use App\Http\Controllers\Bookings\UpdateBookingAmountController;
|
||||
use App\Http\Controllers\Bookings\CreateBookingLockController;
|
||||
use App\Http\Controllers\Bookings\DeleteBookingLockController;
|
||||
use App\Http\Controllers\Bookings\CreateBankingInvoiceTransactionController;
|
||||
use App\Http\Controllers\Bookings\CreateBookingLockController;
|
||||
use App\Http\Controllers\Bookings\DeleteBookingLockController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Bookings'], function () {
|
||||
|
||||
@@ -12,4 +12,6 @@ Route::prefix('rule')
|
||||
|
||||
Route::post('/check/tranfer/period-lock', [CheckRuleController::class, 'checkTransferPeriodLockRule'])->name('check.transfer.period.lock');
|
||||
Route::post('/check/e-invoice/amount-limit', [CheckRuleController::class, 'checkEInvoiceAmountLimitRule'])->name('check.einvoice.amount-limit');
|
||||
|
||||
Route::post('/check/tranfer/period-lock', [CheckRuleController::class, 'checkTransferPeriodLockRule'])->name('check.transfer.period.lock');
|
||||
});
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Settings\CreateLockController;
|
||||
use App\Http\Controllers\Settings\ListLocksController;
|
||||
use App\Http\Controllers\Settings\UpdateLockController;
|
||||
use App\Http\Controllers\KeyValuePairs\CreateLockController;
|
||||
use App\Http\Controllers\KeyValuePairs\ListLocksController;
|
||||
use App\Http\Controllers\KeyValuePairs\UpdateLockController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::prefix('setting')
|
||||
|
||||
@@ -1406,3 +1406,19 @@ Route::get('/run-batch-unfinished-payment-orders', function (Request $request) {
|
||||
Route::get('/locks', function () {
|
||||
return view('pages.dashboards.admin_lock');
|
||||
})->name('admin.admin_lock');
|
||||
|
||||
// Landing Pages
|
||||
$landingPages = [
|
||||
'1688-payment-alternative-cn',
|
||||
'en-1688-vip-landing-page-general-fb',
|
||||
'en-1688-vip-landing-page-general-google',
|
||||
'1688-vip-payment-landing-page-wf-comparison-fb',
|
||||
'1688-vip-payment-landing-page-general-fb',
|
||||
'1688-vip-payment-landing-page-wf-comparison-google',
|
||||
'1688-vip-payment-landing-page-general-google',
|
||||
];
|
||||
foreach ($landingPages as $landingPage) {
|
||||
Route::get('/'.$landingPage, function () use ($landingPage) {
|
||||
return view('pages.landing.'.$landingPage);
|
||||
})->name('landing.'.$landingPage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user