|
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 1067-1072
subtest 'process_invoice_without_tax_rate' => sub {
Link Here
|
| 1067 |
$schema->storage->txn_rollback; |
1067 |
$schema->storage->txn_rollback; |
| 1068 |
}; |
1068 |
}; |
| 1069 |
|
1069 |
|
|
|
1070 |
subtest 'duplicate_po_number_blocking' => sub { |
| 1071 |
plan tests => 2; |
| 1072 |
|
| 1073 |
$schema->storage->txn_begin; |
| 1074 |
|
| 1075 |
my $test_san = '5013546098818'; |
| 1076 |
my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); |
| 1077 |
my $active_period = $builder->build( |
| 1078 |
{ |
| 1079 |
source => 'Aqbudgetperiod', |
| 1080 |
value => { budget_period_active => 1 } |
| 1081 |
} |
| 1082 |
); |
| 1083 |
|
| 1084 |
# Test 1: Auto-orders blocking for duplicate PO numbers |
| 1085 |
subtest 'auto_orders_blocking' => sub { |
| 1086 |
plan tests => 9; |
| 1087 |
|
| 1088 |
$schema->storage->txn_begin; |
| 1089 |
|
| 1090 |
# Create vendor EDI account with auto_orders and po_is_basketname enabled |
| 1091 |
my $account = $builder->build( |
| 1092 |
{ |
| 1093 |
source => 'VendorEdiAccount', |
| 1094 |
value => { |
| 1095 |
description => 'auto_orders duplicate test vendor', |
| 1096 |
transport => 'FILE', |
| 1097 |
plugin => '', |
| 1098 |
san => $test_san, |
| 1099 |
auto_orders => 1, |
| 1100 |
po_is_basketname => 1, |
| 1101 |
} |
| 1102 |
} |
| 1103 |
); |
| 1104 |
|
| 1105 |
my $ean = $builder->build( |
| 1106 |
{ |
| 1107 |
source => 'EdifactEan', |
| 1108 |
value => { |
| 1109 |
description => 'test ean', |
| 1110 |
branchcode => undef, |
| 1111 |
ean => $test_san |
| 1112 |
} |
| 1113 |
} |
| 1114 |
); |
| 1115 |
|
| 1116 |
# Create existing basket with PO number that will conflict |
| 1117 |
my $existing_basket = $builder->build( |
| 1118 |
{ |
| 1119 |
source => 'Aqbasket', |
| 1120 |
value => { |
| 1121 |
basketname => 'orders 23/1', # Same as in QUOTES_SMALL.CEQ |
| 1122 |
booksellerid => $account->{vendor_id}, |
| 1123 |
closedate => undef, |
| 1124 |
} |
| 1125 |
} |
| 1126 |
); |
| 1127 |
|
| 1128 |
# Setup the fund |
| 1129 |
$builder->build( |
| 1130 |
{ |
| 1131 |
source => 'Aqbudget', |
| 1132 |
value => { |
| 1133 |
budget_code => 'REF', |
| 1134 |
budget_period_id => $active_period->{budget_period_id} |
| 1135 |
} |
| 1136 |
} |
| 1137 |
); |
| 1138 |
|
| 1139 |
my $filename = 'QUOTES_SMALL.CEQ'; |
| 1140 |
my $trans = Koha::Edifact::Transport->new( $account->{id} ); |
| 1141 |
$trans->working_directory($dirname); |
| 1142 |
|
| 1143 |
my $mhash = $trans->message_hash(); |
| 1144 |
$mhash->{message_type} = 'QUOTE'; |
| 1145 |
$trans->ingest( $mhash, $filename ); |
| 1146 |
|
| 1147 |
my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); |
| 1148 |
|
| 1149 |
# Clear logger before processing |
| 1150 |
$logger->clear(); |
| 1151 |
|
| 1152 |
# Process quote - should create basket but NOT auto-order due to duplicate PO |
| 1153 |
my $die; |
| 1154 |
eval { |
| 1155 |
process_quote($quote); |
| 1156 |
1; |
| 1157 |
} or do { |
| 1158 |
$die = $@; |
| 1159 |
}; |
| 1160 |
ok( !$die, 'Quote with duplicate PO processed without dying' ); |
| 1161 |
|
| 1162 |
# Verify duplicate PO error was logged during quote processing |
| 1163 |
my $errors = $quote->edifact_errors; |
| 1164 |
ok( $errors->count >= 1, 'Error logged for duplicate PO number' ); |
| 1165 |
|
| 1166 |
my $duplicate_error = $errors->search( { section => 'RFF+ON:orders 23/1' } )->first; |
| 1167 |
ok( $duplicate_error, 'Duplicate PO error found in quote errors' ); |
| 1168 |
|
| 1169 |
# Check that new basket was created |
| 1170 |
my $baskets = Koha::Acquisition::Baskets->search( |
| 1171 |
{ |
| 1172 |
booksellerid => $account->{vendor_id}, |
| 1173 |
basketno => { '!=' => $existing_basket->{basketno} } |
| 1174 |
} |
| 1175 |
); |
| 1176 |
is( $baskets->count, 1, "New basket created despite duplicate PO" ); |
| 1177 |
|
| 1178 |
my $new_basket = $baskets->next; |
| 1179 |
is( $new_basket->basketname, 'orders 23/1', "New basket uses duplicate PO number as name" ); |
| 1180 |
|
| 1181 |
# Critical test: Verify basket was NOT closed (auto-order was blocked) |
| 1182 |
ok( !$new_basket->closedate, 'New basket with duplicate PO was NOT closed (auto-order blocked)' ); |
| 1183 |
|
| 1184 |
# Verify no EDI order was created for the conflicting basket |
| 1185 |
my $edi_orders = $schema->resultset('EdifactMessage')->search( |
| 1186 |
{ |
| 1187 |
message_type => 'ORDERS', |
| 1188 |
basketno => $new_basket->basketno, |
| 1189 |
} |
| 1190 |
); |
| 1191 |
is( $edi_orders->count, 0, 'No EDI order created for basket with duplicate PO' ); |
| 1192 |
|
| 1193 |
# Check that the blocking is working by verifying no EDI orders were created |
| 1194 |
# This is the most important test - the basket should NOT be auto-ordered |
| 1195 |
ok( $edi_orders->count == 0, 'Auto-order was blocked - no EDI order created for duplicate PO' ); |
| 1196 |
|
| 1197 |
# Verify that duplicate PO error was logged (this shows detection is working) |
| 1198 |
ok( $duplicate_error, 'Duplicate PO number detection and logging is working' ); |
| 1199 |
|
| 1200 |
$schema->storage->txn_rollback; |
| 1201 |
}; |
| 1202 |
|
| 1203 |
# Test 2: No blocking when po_is_basketname is disabled |
| 1204 |
subtest 'no_blocking_when_feature_disabled' => sub { |
| 1205 |
plan tests => 5; |
| 1206 |
|
| 1207 |
$schema->storage->txn_begin; |
| 1208 |
|
| 1209 |
# Create vendor EDI account with po_is_basketname DISABLED |
| 1210 |
my $account = $builder->build( |
| 1211 |
{ |
| 1212 |
source => 'VendorEdiAccount', |
| 1213 |
value => { |
| 1214 |
description => 'feature disabled test vendor', |
| 1215 |
transport => 'FILE', |
| 1216 |
plugin => '', |
| 1217 |
san => $test_san, |
| 1218 |
auto_orders => 1, |
| 1219 |
po_is_basketname => 0, # Feature disabled |
| 1220 |
} |
| 1221 |
} |
| 1222 |
); |
| 1223 |
|
| 1224 |
my $ean = $builder->build( |
| 1225 |
{ |
| 1226 |
source => 'EdifactEan', |
| 1227 |
value => { |
| 1228 |
description => 'test ean', |
| 1229 |
branchcode => undef, |
| 1230 |
ean => $test_san |
| 1231 |
} |
| 1232 |
} |
| 1233 |
); |
| 1234 |
|
| 1235 |
# Create existing basket with any name |
| 1236 |
my $existing_basket = $builder->build( |
| 1237 |
{ |
| 1238 |
source => 'Aqbasket', |
| 1239 |
value => { |
| 1240 |
basketname => 'orders 23/1', |
| 1241 |
booksellerid => $account->{vendor_id}, |
| 1242 |
closedate => undef, |
| 1243 |
} |
| 1244 |
} |
| 1245 |
); |
| 1246 |
|
| 1247 |
# Setup the fund |
| 1248 |
$builder->build( |
| 1249 |
{ |
| 1250 |
source => 'Aqbudget', |
| 1251 |
value => { |
| 1252 |
budget_code => 'REF', |
| 1253 |
budget_period_id => $active_period->{budget_period_id} |
| 1254 |
} |
| 1255 |
} |
| 1256 |
); |
| 1257 |
|
| 1258 |
my $filename = 'QUOTES_SMALL.CEQ'; |
| 1259 |
my $trans = Koha::Edifact::Transport->new( $account->{id} ); |
| 1260 |
$trans->working_directory($dirname); |
| 1261 |
|
| 1262 |
my $mhash = $trans->message_hash(); |
| 1263 |
$mhash->{message_type} = 'QUOTE'; |
| 1264 |
$trans->ingest( $mhash, $filename ); |
| 1265 |
|
| 1266 |
my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); |
| 1267 |
|
| 1268 |
$logger->clear(); |
| 1269 |
process_quote($quote); |
| 1270 |
|
| 1271 |
# Verify new basket was created and auto-ordered (no blocking) |
| 1272 |
my $baskets = Koha::Acquisition::Baskets->search( |
| 1273 |
{ |
| 1274 |
booksellerid => $account->{vendor_id}, |
| 1275 |
basketno => { '!=' => $existing_basket->{basketno} } |
| 1276 |
} |
| 1277 |
); |
| 1278 |
is( $baskets->count, 1, "New basket created" ); |
| 1279 |
|
| 1280 |
my $new_basket = $baskets->next; |
| 1281 |
|
| 1282 |
# When po_is_basketname is disabled, basket uses filename not PO number |
| 1283 |
is( $new_basket->basketname, $filename, "Basket uses filename when po_is_basketname disabled" ); |
| 1284 |
|
| 1285 |
# The key test is that normal processing occurred without duplicate detection |
| 1286 |
# Since po_is_basketname is disabled, basket should use filename not PO number |
| 1287 |
ok( $new_basket->basketname eq $filename, 'Normal basket naming when feature disabled' ); |
| 1288 |
|
| 1289 |
# With po_is_basketname disabled, quote processing should work normally |
| 1290 |
# The absence of duplicate errors in the database is the key indicator |
| 1291 |
my $quote_errors = $schema->resultset('EdifactError')->search( {} ); |
| 1292 |
my $has_duplicate_db_error = grep { $_->details =~ /Duplicate purchase order/ } $quote_errors->all; |
| 1293 |
ok( !$has_duplicate_db_error, 'No duplicate PO database errors when feature disabled' ); |
| 1294 |
|
| 1295 |
pass('Feature correctly disabled - normal processing occurred'); |
| 1296 |
|
| 1297 |
$schema->storage->txn_rollback; |
| 1298 |
}; |
| 1299 |
|
| 1300 |
$schema->storage->txn_rollback; |
| 1301 |
}; |
| 1302 |
|
| 1070 |
subtest 'create_edi_order_logging' => sub { |
1303 |
subtest 'create_edi_order_logging' => sub { |
| 1071 |
plan tests => 8; |
1304 |
plan tests => 8; |
| 1072 |
|
1305 |
|
| 1073 |
- |
|
|