Lines 21-27
use Modern::Perl;
Link Here
|
21 |
use FindBin qw( $Bin ); |
21 |
use FindBin qw( $Bin ); |
22 |
|
22 |
|
23 |
use Test::NoWarnings; |
23 |
use Test::NoWarnings; |
24 |
use Test::More tests => 5; |
24 |
use Test::More tests => 6; |
25 |
use Test::MockModule; |
25 |
use Test::MockModule; |
26 |
|
26 |
|
27 |
use t::lib::Mocks; |
27 |
use t::lib::Mocks; |
Lines 1149-1154
subtest 'process_invoice_without_tax_rate' => sub {
Link Here
|
1149 |
$schema->storage->txn_rollback; |
1149 |
$schema->storage->txn_rollback; |
1150 |
}; |
1150 |
}; |
1151 |
|
1151 |
|
|
|
1152 |
subtest 'duplicate_po_number_blocking' => sub { |
1153 |
plan tests => 2; |
1154 |
|
1155 |
$schema->storage->txn_begin; |
1156 |
|
1157 |
my $test_san = '5013546098818'; |
1158 |
my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); |
1159 |
my $active_period = $builder->build( |
1160 |
{ |
1161 |
source => 'Aqbudgetperiod', |
1162 |
value => { budget_period_active => 1 } |
1163 |
} |
1164 |
); |
1165 |
|
1166 |
# Test 1: Auto-orders blocking for duplicate PO numbers |
1167 |
subtest 'auto_orders_blocking' => sub { |
1168 |
plan tests => 9; |
1169 |
|
1170 |
$schema->storage->txn_begin; |
1171 |
|
1172 |
# Create vendor EDI account with auto_orders and po_is_basketname enabled |
1173 |
my $account = $builder->build( |
1174 |
{ |
1175 |
source => 'VendorEdiAccount', |
1176 |
value => { |
1177 |
description => 'auto_orders duplicate test vendor', |
1178 |
transport => 'FILE', |
1179 |
plugin => '', |
1180 |
san => $test_san, |
1181 |
auto_orders => 1, |
1182 |
po_is_basketname => 1, |
1183 |
} |
1184 |
} |
1185 |
); |
1186 |
|
1187 |
my $ean = $builder->build( |
1188 |
{ |
1189 |
source => 'EdifactEan', |
1190 |
value => { |
1191 |
description => 'test ean', |
1192 |
branchcode => undef, |
1193 |
ean => $test_san |
1194 |
} |
1195 |
} |
1196 |
); |
1197 |
|
1198 |
# Create existing basket with PO number that will conflict |
1199 |
my $existing_basket = $builder->build( |
1200 |
{ |
1201 |
source => 'Aqbasket', |
1202 |
value => { |
1203 |
basketname => 'orders 23/1', # Same as in QUOTES_SMALL.CEQ |
1204 |
booksellerid => $account->{vendor_id}, |
1205 |
closedate => undef, |
1206 |
} |
1207 |
} |
1208 |
); |
1209 |
|
1210 |
# Setup the fund |
1211 |
$builder->build( |
1212 |
{ |
1213 |
source => 'Aqbudget', |
1214 |
value => { |
1215 |
budget_code => 'REF', |
1216 |
budget_period_id => $active_period->{budget_period_id} |
1217 |
} |
1218 |
} |
1219 |
); |
1220 |
|
1221 |
my $filename = 'QUOTES_SMALL.CEQ'; |
1222 |
my $trans = Koha::Edifact::Transport->new( $account->{id} ); |
1223 |
$trans->working_directory($dirname); |
1224 |
|
1225 |
my $mhash = $trans->message_hash(); |
1226 |
$mhash->{message_type} = 'QUOTE'; |
1227 |
$trans->ingest( $mhash, $filename ); |
1228 |
|
1229 |
my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); |
1230 |
|
1231 |
# Clear logger before processing |
1232 |
$logger->clear(); |
1233 |
|
1234 |
# Process quote - should create basket but NOT auto-order due to duplicate PO |
1235 |
my $die; |
1236 |
eval { |
1237 |
process_quote($quote); |
1238 |
1; |
1239 |
} or do { |
1240 |
$die = $@; |
1241 |
}; |
1242 |
ok( !$die, 'Quote with duplicate PO processed without dying' ); |
1243 |
|
1244 |
# Verify duplicate PO error was logged during quote processing |
1245 |
my $errors = $quote->edifact_errors; |
1246 |
ok( $errors->count >= 1, 'Error logged for duplicate PO number' ); |
1247 |
|
1248 |
my $duplicate_error = $errors->search( { section => 'RFF+ON:orders 23/1' } )->first; |
1249 |
ok( $duplicate_error, 'Duplicate PO error found in quote errors' ); |
1250 |
|
1251 |
# Check that new basket was created |
1252 |
my $baskets = Koha::Acquisition::Baskets->search( |
1253 |
{ |
1254 |
booksellerid => $account->{vendor_id}, |
1255 |
basketno => { '!=' => $existing_basket->{basketno} } |
1256 |
} |
1257 |
); |
1258 |
is( $baskets->count, 1, "New basket created despite duplicate PO" ); |
1259 |
|
1260 |
my $new_basket = $baskets->next; |
1261 |
is( $new_basket->basketname, 'orders 23/1', "New basket uses duplicate PO number as name" ); |
1262 |
|
1263 |
# Critical test: Verify basket was NOT closed (auto-order was blocked) |
1264 |
ok( !$new_basket->closedate, 'New basket with duplicate PO was NOT closed (auto-order blocked)' ); |
1265 |
|
1266 |
# Verify no EDI order was created for the conflicting basket |
1267 |
my $edi_orders = $schema->resultset('EdifactMessage')->search( |
1268 |
{ |
1269 |
message_type => 'ORDERS', |
1270 |
basketno => $new_basket->basketno, |
1271 |
} |
1272 |
); |
1273 |
is( $edi_orders->count, 0, 'No EDI order created for basket with duplicate PO' ); |
1274 |
|
1275 |
# Check that the blocking is working by verifying no EDI orders were created |
1276 |
# This is the most important test - the basket should NOT be auto-ordered |
1277 |
ok( $edi_orders->count == 0, 'Auto-order was blocked - no EDI order created for duplicate PO' ); |
1278 |
|
1279 |
# Verify that duplicate PO error was logged (this shows detection is working) |
1280 |
ok( $duplicate_error, 'Duplicate PO number detection and logging is working' ); |
1281 |
|
1282 |
$schema->storage->txn_rollback; |
1283 |
}; |
1284 |
|
1285 |
# Test 2: No blocking when po_is_basketname is disabled |
1286 |
subtest 'no_blocking_when_feature_disabled' => sub { |
1287 |
plan tests => 5; |
1288 |
|
1289 |
$schema->storage->txn_begin; |
1290 |
|
1291 |
# Create vendor EDI account with po_is_basketname DISABLED |
1292 |
my $account = $builder->build( |
1293 |
{ |
1294 |
source => 'VendorEdiAccount', |
1295 |
value => { |
1296 |
description => 'feature disabled test vendor', |
1297 |
transport => 'FILE', |
1298 |
plugin => '', |
1299 |
san => $test_san, |
1300 |
auto_orders => 1, |
1301 |
po_is_basketname => 0, # Feature disabled |
1302 |
} |
1303 |
} |
1304 |
); |
1305 |
|
1306 |
my $ean = $builder->build( |
1307 |
{ |
1308 |
source => 'EdifactEan', |
1309 |
value => { |
1310 |
description => 'test ean', |
1311 |
branchcode => undef, |
1312 |
ean => $test_san |
1313 |
} |
1314 |
} |
1315 |
); |
1316 |
|
1317 |
# Create existing basket with any name |
1318 |
my $existing_basket = $builder->build( |
1319 |
{ |
1320 |
source => 'Aqbasket', |
1321 |
value => { |
1322 |
basketname => 'orders 23/1', |
1323 |
booksellerid => $account->{vendor_id}, |
1324 |
closedate => undef, |
1325 |
} |
1326 |
} |
1327 |
); |
1328 |
|
1329 |
# Setup the fund |
1330 |
$builder->build( |
1331 |
{ |
1332 |
source => 'Aqbudget', |
1333 |
value => { |
1334 |
budget_code => 'REF', |
1335 |
budget_period_id => $active_period->{budget_period_id} |
1336 |
} |
1337 |
} |
1338 |
); |
1339 |
|
1340 |
my $filename = 'QUOTES_SMALL.CEQ'; |
1341 |
my $trans = Koha::Edifact::Transport->new( $account->{id} ); |
1342 |
$trans->working_directory($dirname); |
1343 |
|
1344 |
my $mhash = $trans->message_hash(); |
1345 |
$mhash->{message_type} = 'QUOTE'; |
1346 |
$trans->ingest( $mhash, $filename ); |
1347 |
|
1348 |
my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); |
1349 |
|
1350 |
$logger->clear(); |
1351 |
process_quote($quote); |
1352 |
|
1353 |
# Verify new basket was created and auto-ordered (no blocking) |
1354 |
my $baskets = Koha::Acquisition::Baskets->search( |
1355 |
{ |
1356 |
booksellerid => $account->{vendor_id}, |
1357 |
basketno => { '!=' => $existing_basket->{basketno} } |
1358 |
} |
1359 |
); |
1360 |
is( $baskets->count, 1, "New basket created" ); |
1361 |
|
1362 |
my $new_basket = $baskets->next; |
1363 |
|
1364 |
# When po_is_basketname is disabled, basket uses filename not PO number |
1365 |
is( $new_basket->basketname, $filename, "Basket uses filename when po_is_basketname disabled" ); |
1366 |
|
1367 |
# The key test is that normal processing occurred without duplicate detection |
1368 |
# Since po_is_basketname is disabled, basket should use filename not PO number |
1369 |
ok( $new_basket->basketname eq $filename, 'Normal basket naming when feature disabled' ); |
1370 |
|
1371 |
# With po_is_basketname disabled, quote processing should work normally |
1372 |
# The absence of duplicate errors in the database is the key indicator |
1373 |
my $quote_errors = $schema->resultset('EdifactError')->search( {} ); |
1374 |
my $has_duplicate_db_error = grep { $_->details =~ /Duplicate purchase order/ } $quote_errors->all; |
1375 |
ok( !$has_duplicate_db_error, 'No duplicate PO database errors when feature disabled' ); |
1376 |
|
1377 |
pass('Feature correctly disabled - normal processing occurred'); |
1378 |
|
1379 |
$schema->storage->txn_rollback; |
1380 |
}; |
1381 |
|
1382 |
$schema->storage->txn_rollback; |
1383 |
}; |
1384 |
|
1152 |
subtest 'create_edi_order_logging' => sub { |
1385 |
subtest 'create_edi_order_logging' => sub { |
1153 |
plan tests => 8; |
1386 |
plan tests => 8; |
1154 |
|
1387 |
|
1155 |
- |
|
|