255 lines
11 KiB
PHP
255 lines
11 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
usesApiSuite();
|
|
|
|
function bulk_action_order_item_deleted_at(int $orderItemId): ?string
|
|
{
|
|
$row = api_test_runtime()->queryOne('SELECT deleted_at FROM order_items WHERE id = ' . $orderItemId . ' LIMIT 1');
|
|
return $row['deleted_at'] ?? null;
|
|
}
|
|
|
|
function bulk_action_order_invoice_collection_id(int $orderId): int
|
|
{
|
|
$row = api_test_runtime()->queryOne('SELECT invoice_collection_id FROM orders WHERE id = ' . $orderId . ' LIMIT 1');
|
|
return (int)($row['invoice_collection_id'] ?? 0);
|
|
}
|
|
|
|
function bulk_action_configure_rule_product(string $attribute, int $productId): void
|
|
{
|
|
new \classes\customer_rule_product_restriction_service();
|
|
$db = api_test_runtime()->db();
|
|
$safeAttribute = $db->real_escape_string($attribute);
|
|
$result = $db->query(
|
|
"SELECT id FROM customer_rule_product_collections WHERE attribute = '{$safeAttribute}' ORDER BY sort_order, id LIMIT 1"
|
|
);
|
|
$collectionId = (int)$result->fetch_assoc()['id'];
|
|
$db->query(
|
|
"INSERT IGNORE INTO customer_rule_product_collection_products (collection_id, product_id)
|
|
VALUES ({$collectionId}, {$productId})"
|
|
);
|
|
api_fixtures()->cleanupDeleteWhere('customer_rule_product_collection_products', [
|
|
'collection_id' => $collectionId,
|
|
'product_id' => $productId,
|
|
]);
|
|
}
|
|
|
|
it('previews and applies customer rule cleanup only after exact typed confirmation', function (): void {
|
|
api_test_covers('POST /collected-invoices/bulk-actions/preview', 'customer-rule-cleanup');
|
|
api_test_covers('POST /collected-invoices/bulk-actions/apply', 'customer-rule-cleanup');
|
|
|
|
$customer = api_fixtures()->createUser(['display_name' => 'Bulk Cleanup Customer']);
|
|
api_fixtures()->addCustomerAttribute((int)$customer['id'], 'restrictSpotFree');
|
|
$department = api_fixtures()->createDepartment();
|
|
$invoiceCollection = api_fixtures()->createInvoiceCollection([
|
|
'customer_number' => $customer['customer_number'],
|
|
]);
|
|
$order = api_fixtures()->createOrder([
|
|
'customer_id' => $customer['customer_number'],
|
|
'department_id' => $department['id'],
|
|
'invoice_collection_id' => $invoiceCollection['id'],
|
|
]);
|
|
$product = api_fixtures()->createProduct([
|
|
'name' => 'Spot Free rinse',
|
|
'price' => 80,
|
|
]);
|
|
bulk_action_configure_rule_product('restrictSpotFree', (int)$product['id']);
|
|
$orderItem = api_fixtures()->createOrderItem([
|
|
'order_id' => $order['id'],
|
|
'product_id' => $product['id'],
|
|
'cashier_id' => 1,
|
|
'price' => 80,
|
|
]);
|
|
$session = api_fixtures()->createUserSession(['reset_collected_invoice_economic']);
|
|
|
|
$previewResponse = api_client()->post('/collected-invoices/bulk-actions/preview', [
|
|
'action' => 'remove_customer_rule_violations',
|
|
'invoice_collection_ids' => [$invoiceCollection['id']],
|
|
'locale' => 'da',
|
|
], $session['headers']);
|
|
|
|
$previewResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$preview = $previewResponse->data();
|
|
expect($preview['preview_id'] ?? null)->toBeString()
|
|
->and($preview['confirmation_phrase'] ?? null)->toBe('Bekræft')
|
|
->and($preview['summary']['changed_count'] ?? null)->toBe(1)
|
|
->and($preview['order_items'][0]['order_item_id'] ?? null)->toBe((int)$orderItem['id'])
|
|
->and(bulk_action_order_item_deleted_at((int)$orderItem['id']))->toBeNull();
|
|
|
|
api_client()->post('/collected-invoices/bulk-actions/apply', [
|
|
'preview_id' => $preview['preview_id'],
|
|
'action' => 'remove_customer_rule_violations',
|
|
'invoice_collection_ids' => [$invoiceCollection['id']],
|
|
'confirmation_text' => 'Bekraeft',
|
|
'locale' => 'da',
|
|
], $session['headers'])
|
|
->assertStatus(400)
|
|
->assertEnvelope()
|
|
->assertSuccess(false);
|
|
|
|
expect(bulk_action_order_item_deleted_at((int)$orderItem['id']))->toBeNull();
|
|
|
|
$applyResponse = api_client()->post('/collected-invoices/bulk-actions/apply', [
|
|
'preview_id' => $preview['preview_id'],
|
|
'action' => 'remove_customer_rule_violations',
|
|
'invoice_collection_ids' => [$invoiceCollection['id']],
|
|
'confirmation_text' => 'Bekræft',
|
|
'locale' => 'da',
|
|
], $session['headers']);
|
|
|
|
$applyResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$applied = $applyResponse->data();
|
|
expect($applied['preview'] ?? null)->toBeFalse()
|
|
->and($applied['result']['changed_count'] ?? null)->toBe(1)
|
|
->and(bulk_action_order_item_deleted_at((int)$orderItem['id']))->not->toBeNull();
|
|
});
|
|
|
|
it('previews and applies customer rule cleanup for both spotfree addon products', function (): void {
|
|
api_test_covers('POST /collected-invoices/bulk-actions/preview', 'customer-rule-cleanup-spotfree-addons');
|
|
api_test_covers('POST /collected-invoices/bulk-actions/apply', 'customer-rule-cleanup-spotfree-addons');
|
|
|
|
$customer = api_fixtures()->createUser(['display_name' => 'Bulk Cleanup Spotfree Addons Customer']);
|
|
api_fixtures()->addCustomerAttribute((int)$customer['id'], 'restrictSpotFree');
|
|
$department = api_fixtures()->createDepartment();
|
|
$invoiceCollection = api_fixtures()->createInvoiceCollection([
|
|
'customer_number' => $customer['customer_number'],
|
|
]);
|
|
$order = api_fixtures()->createOrder([
|
|
'customer_id' => $customer['customer_number'],
|
|
'department_id' => $department['id'],
|
|
'invoice_collection_id' => $invoiceCollection['id'],
|
|
]);
|
|
$spotfreeVanProduct = api_fixtures()->createProduct([
|
|
'id' => 23,
|
|
'name' => 'Skylning med RO - Varevogn',
|
|
'category' => 4,
|
|
'price' => 39,
|
|
]);
|
|
$spotfreeTruckProduct = api_fixtures()->createProduct([
|
|
'id' => 24,
|
|
'name' => 'Skylning med RO - Lastbil',
|
|
'category' => 4,
|
|
'price' => 39,
|
|
]);
|
|
bulk_action_configure_rule_product('restrictSpotFree', (int)$spotfreeVanProduct['id']);
|
|
bulk_action_configure_rule_product('restrictSpotFree', (int)$spotfreeTruckProduct['id']);
|
|
$vanOrderItem = api_fixtures()->createOrderItem([
|
|
'order_id' => $order['id'],
|
|
'product_id' => $spotfreeVanProduct['id'],
|
|
'cashier_id' => 1,
|
|
'price' => 39,
|
|
]);
|
|
$truckOrderItem = api_fixtures()->createOrderItem([
|
|
'order_id' => $order['id'],
|
|
'product_id' => $spotfreeTruckProduct['id'],
|
|
'cashier_id' => 1,
|
|
'price' => 39,
|
|
]);
|
|
$session = api_fixtures()->createUserSession(['reset_collected_invoice_economic']);
|
|
|
|
$previewResponse = api_client()->post('/collected-invoices/bulk-actions/preview', [
|
|
'action' => 'remove_customer_rule_violations',
|
|
'invoice_collection_ids' => [$invoiceCollection['id']],
|
|
'locale' => 'en',
|
|
], $session['headers']);
|
|
|
|
$previewResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$preview = $previewResponse->data();
|
|
$previewOrderItemIds = array_map('intval', array_column($preview['order_items'] ?? [], 'order_item_id'));
|
|
sort($previewOrderItemIds);
|
|
|
|
expect($preview['summary']['changed_count'] ?? null)->toBe(2)
|
|
->and($previewOrderItemIds)->toBe([(int)$vanOrderItem['id'], (int)$truckOrderItem['id']])
|
|
->and(bulk_action_order_item_deleted_at((int)$vanOrderItem['id']))->toBeNull()
|
|
->and(bulk_action_order_item_deleted_at((int)$truckOrderItem['id']))->toBeNull();
|
|
|
|
$applyResponse = api_client()->post('/collected-invoices/bulk-actions/apply', [
|
|
'preview_id' => $preview['preview_id'],
|
|
'action' => 'remove_customer_rule_violations',
|
|
'invoice_collection_ids' => [$invoiceCollection['id']],
|
|
'confirmation_text' => 'Confirm',
|
|
'locale' => 'en',
|
|
], $session['headers']);
|
|
|
|
$applyResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
expect(bulk_action_order_item_deleted_at((int)$vanOrderItem['id']))->not->toBeNull()
|
|
->and(bulk_action_order_item_deleted_at((int)$truckOrderItem['id']))->not->toBeNull();
|
|
});
|
|
|
|
it('merges selected invoice collections into the explicit target after confirmation', function (): void {
|
|
api_test_covers('POST /collected-invoices/bulk-actions/preview', 'merge');
|
|
api_test_covers('POST /collected-invoices/bulk-actions/apply', 'merge');
|
|
|
|
$customer = api_fixtures()->createUser(['display_name' => 'Bulk Merge Customer']);
|
|
$department = api_fixtures()->createDepartment();
|
|
$targetCollection = api_fixtures()->createInvoiceCollection([
|
|
'customer_number' => $customer['customer_number'],
|
|
]);
|
|
$sourceCollection = api_fixtures()->createInvoiceCollection([
|
|
'customer_number' => $customer['customer_number'],
|
|
]);
|
|
$targetOrder = api_fixtures()->createOrder([
|
|
'customer_id' => $customer['customer_number'],
|
|
'department_id' => $department['id'],
|
|
'invoice_collection_id' => $targetCollection['id'],
|
|
]);
|
|
$sourceOrder = api_fixtures()->createOrder([
|
|
'customer_id' => $customer['customer_number'],
|
|
'department_id' => $department['id'],
|
|
'invoice_collection_id' => $sourceCollection['id'],
|
|
]);
|
|
$session = api_fixtures()->createUserSession(['move_collected_invoice']);
|
|
|
|
$previewResponse = api_client()->post('/collected-invoices/bulk-actions/preview', [
|
|
'action' => 'merge_collections',
|
|
'invoice_collection_ids' => [$sourceCollection['id'], $targetCollection['id']],
|
|
'options' => ['target_invoice_collection_id' => $targetCollection['id']],
|
|
'locale' => 'en',
|
|
], $session['headers']);
|
|
|
|
$previewResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$preview = $previewResponse->data();
|
|
expect($preview['confirmation_phrase'] ?? null)->toBe('Confirm')
|
|
->and($preview['target_invoice_collection_id'] ?? null)->toBe((int)$targetCollection['id'])
|
|
->and($preview['summary']['orders_to_move'] ?? null)->toBe(1)
|
|
->and(bulk_action_order_invoice_collection_id((int)$sourceOrder['id']))->toBe((int)$sourceCollection['id']);
|
|
|
|
$applyResponse = api_client()->post('/collected-invoices/bulk-actions/apply', [
|
|
'preview_id' => $preview['preview_id'],
|
|
'action' => 'merge_collections',
|
|
'invoice_collection_ids' => [$sourceCollection['id'], $targetCollection['id']],
|
|
'options' => ['target_invoice_collection_id' => $targetCollection['id']],
|
|
'confirmation_text' => 'Confirm',
|
|
'locale' => 'en',
|
|
], $session['headers']);
|
|
|
|
$applyResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
expect(bulk_action_order_invoice_collection_id((int)$sourceOrder['id']))->toBe((int)$targetCollection['id'])
|
|
->and(bulk_action_order_invoice_collection_id((int)$targetOrder['id']))->toBe((int)$targetCollection['id']);
|
|
});
|