diff --git a/.rubocop.yml b/.rubocop.yml index 1c755ec..97f1752 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -18,6 +18,10 @@ Style/Documentation: Metrics/ParameterLists: Max: 8 +Lint/MissingSuper: + Exclude: + - app/services/**/* + Metrics/BlockLength: Exclude: - spec/**/* diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 46f10ee..6e462d5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2026-01-27 11:43:39 UTC using RuboCop version 1.84.0. +# on 2026-01-27 12:23:34 UTC using RuboCop version 1.84.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -13,7 +13,17 @@ Lint/RedundantCopDisableDirective: - 'app/jobs/update_sparta_state_job.rb' - 'app/services/spl/sparta_loyalty_service.rb' -# Offense count: 8 +# Offense count: 3 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 18 + +# Offense count: 2 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 8 + +# Offense count: 13 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 14 @@ -21,7 +31,7 @@ Metrics/MethodLength: # Offense count: 1 # Configuration parameters: CountComments, CountAsOne. Metrics/ModuleLength: - Max: 125 + Max: 156 # Offense count: 2 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. @@ -82,7 +92,7 @@ Style/IfUnlessModifier: - 'app/services/assign_sparta_card_number_service.rb' - 'app/services/spl/validate_card_service.rb' -# Offense count: 4 +# Offense count: 5 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https diff --git a/Gemfile.lock b/Gemfile.lock index b95f23d..236cfd7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,8 +10,8 @@ PATH rspec-rails rspec-retry rubocop-rspec - spree (~> 5.1, >= 5.1.4) - spree_api (~> 5.1, >= 5.1.4) + spree (~> 5.2, >= 5.2.4) + spree_api (~> 5.2, >= 5.2.4) spree_auth_devise spree_dev_tools @@ -228,7 +228,14 @@ GEM faraday-net_http (3.4.2) net-http (~> 0.5) ffaker (2.25.0) + ffi (1.17.3-aarch64-linux-gnu) + ffi (1.17.3-aarch64-linux-musl) + ffi (1.17.3-arm-linux-gnu) + ffi (1.17.3-arm-linux-musl) + ffi (1.17.3-arm64-darwin) ffi (1.17.3-x86_64-darwin) + ffi (1.17.3-x86_64-linux-gnu) + ffi (1.17.3-x86_64-linux-musl) fiber-annotation (0.2.0) fiber-local (1.1.0) fiber-storage @@ -358,8 +365,22 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.5) + nokogiri (1.19.0-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.0-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.19.0-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.0-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.19.0-arm64-darwin) + racc (~> 1.4) nokogiri (1.19.0-x86_64-darwin) racc (~> 1.4) + nokogiri (1.19.0-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.0-x86_64-linux-musl) + racc (~> 1.4) observer (0.1.2) octokit (4.25.1) faraday (>= 1, < 3) @@ -674,7 +695,14 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) + sqlite3 (2.9.0-aarch64-linux-gnu) + sqlite3 (2.9.0-aarch64-linux-musl) + sqlite3 (2.9.0-arm-linux-gnu) + sqlite3 (2.9.0-arm-linux-musl) + sqlite3 (2.9.0-arm64-darwin) sqlite3 (2.9.0-x86_64-darwin) + sqlite3 (2.9.0-x86_64-linux-gnu) + sqlite3 (2.9.0-x86_64-linux-musl) state_machines (0.100.4) state_machines-activemodel (0.101.0) activemodel (>= 7.2) @@ -689,7 +717,13 @@ GEM tailwindcss-rails (4.4.0) railties (>= 7.0.0) tailwindcss-ruby (~> 4.0) + tailwindcss-ruby (4.1.18) + tailwindcss-ruby (4.1.18-aarch64-linux-gnu) + tailwindcss-ruby (4.1.18-aarch64-linux-musl) + tailwindcss-ruby (4.1.18-arm64-darwin) tailwindcss-ruby (4.1.18-x86_64-darwin) + tailwindcss-ruby (4.1.18-x86_64-linux-gnu) + tailwindcss-ruby (4.1.18-x86_64-linux-musl) terminal-table (4.0.0) unicode-display_width (>= 1.1.1, < 4) thor (1.5.0) @@ -766,5 +800,279 @@ DEPENDENCIES sqlite3 (>= 2.0) webmock +CHECKSUMS + abbrev (0.1.2) sha256=ad1b4eaaaed4cb722d5684d63949e4bde1d34f2a95e20db93aecfe7cbac74242 + action_text-trix (2.1.16) sha256=f645a2c21821b8449fd1d6770708f4031c91a2eedf9ef476e9be93c64e703a8a + actioncable (8.1.2) sha256=dc31efc34cca9cdefc5c691ddb8b4b214c0ea5cd1372108cbc1377767fb91969 + actionmailbox (8.1.2) sha256=058b2fb1980e5d5a894f675475fcfa45c62631103d5a2596d9610ec81581889b + actionmailer (8.1.2) sha256=f4c1d2060f653bfe908aa7fdc5a61c0e5279670de992146582f2e36f8b9175e9 + actionpack (8.1.2) sha256=ced74147a1f0daafaa4bab7f677513fd4d3add574c7839958f7b4f1de44f8423 + actiontext (8.1.2) sha256=0bf57da22a9c19d970779c3ce24a56be31b51c7640f2763ec64aa72e358d2d2d + actionview (8.1.2) sha256=80455b2588911c9b72cec22d240edacb7c150e800ef2234821269b2b2c3e2e5b + active_link_to (1.0.5) sha256=4830847b3d14589df1e9fc62038ceec015257fce975ec1c2a77836c461b139ba + active_storage_validations (1.3.0) sha256=788e4189d51c7b55049bf2825ede964baa2fe531e22a31c59f67a962ebf8d71e + activejob (8.1.2) sha256=908dab3713b101859536375819f4156b07bdf4c232cc645e7538adb9e302f825 + activemerchant (1.137.0) sha256=fdf5e33f5c94d1981bd632d72e282c0a5afaf06bac6df3f933c08a95e98bd5ce + activemodel (8.1.2) sha256=e21358c11ce68aed3f9838b7e464977bc007b4446c6e4059781e1d5c03bcf33e + activerecord (8.1.2) sha256=acfbe0cadfcc50fa208011fe6f4eb01cae682ebae0ef57145ba45380c74bcc44 + activestorage (8.1.2) sha256=8a63a48c3999caeee26a59441f813f94681fc35cc41aba7ce1f836add04fba76 + activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae + acts-as-taggable-on (13.0.0) sha256=dca776c6ddebc458d175b57554ad692488e283f27047117e01ed871f1cba6135 + acts_as_list (1.2.6) sha256=8345380900b7bee620c07ad00991ccee59af3d8c9e8574f426e321da2865fdc8 + addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + any_ascii (0.3.3) sha256=9bba37e4aadc7c57bc29e4bae520418416d1b69ea167d04f2aeaf9c07166f724 + ar_lazy_preload (2.1.0) sha256=03effc2aac5aef2a1be8ff3ed4bb60f4e92e57f192dde61750bd8ea2131ad517 + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + async (2.36.0) sha256=090623f4c65706664355c9efa6c7bfb86771a513e65cd681c51cb27747530550 + async-http (0.94.2) sha256=c5ca94b337976578904a373833abe5b8dfb466a2946af75c4ae38c409c5c78b2 + async-http-faraday (0.22.1) sha256=414c3197f32157bc0a7a187b1fb4c669097a8ef71832613eff2371c9808e9923 + async-pool (0.11.1) sha256=98e1583e199a75f7dc70f8e65fc8d0d3b28636c3f256595d43e206642ad8fbda + awesome_nested_set (3.9.0) sha256=3ce99e816550f97f4de118e621630070aacf24928b920fe4a68846578a8daaed + awesome_print (1.9.2) sha256=e99b32b704acff16d768b3468680793ced40bfdc4537eb07e06a4be11133786e + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bcrypt (3.1.21) sha256=5964613d750a42c7ee5dc61f7b9336fb6caca429ba4ac9f2011609946e4a2dcf + bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + brakeman (7.1.2) sha256=6b04927710a2e7d13a72248b5d404c633188e02417f28f3d853e4b6370d26dce + breadcrumbs_on_rails (4.1.0) sha256=6146ecf669f6251507231028719d51d92b8f42f1f982b83a2481fa1465cb6cee + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + byebug (13.0.0) sha256=d2263efe751941ca520fa29744b71972d39cbc41839496706f5d9b22e92ae05d + cancancan (3.6.1) sha256=975c1d5cbf58d5df48a9452a7f61ae3d254608cd87570402f5925a8864c56b62 + capybara (3.40.0) sha256=42dba720578ea1ca65fd7a41d163dd368502c191804558f6e0f71b391054aeef + capybara-screenshot (1.0.26) sha256=816b9370a07752097c82a05f568aaf5d3b7f45c3db5d3aab2014071e1b3c0c77 + carmen (1.1.3) sha256=970dbcb6a1743f0c7d765ebf4f0e5b59e99c4f96460baaa22e7306d5a2952e68 + chartkick (5.2.1) sha256=2848d7de87189f30f28d077eb0bbdebc8a1f0f6f81de1ded95008fe564369949 + childprocess (5.1.0) sha256=9a8d484be2fd4096a0e90a0cd3e449a05bc3aa33f8ac9e4d6dcef6ac1455b6ec + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a + console (1.34.2) sha256=1c036abf606ccec83f9dc28f0c31710fe5936ffe7ba5d235ae2865590a482d58 + countries (8.1.0) sha256=4d6b318b8e906f1f769d5c021c13a418d33e917dc96ceb625a91d8e7ab2d192e + crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e + crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d + csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f + database_cleaner (2.1.0) sha256=1dcba26e3b1576da692fc6bac10136a4744da5bcc293d248aae19640c65d89cd + database_cleaner-active_record (2.2.2) sha256=88296b9f3088c31f7c0d4fcec10f68e4b71c96698043916de59b04debec10388 + database_cleaner-core (2.0.1) sha256=8646574c32162e59ed7b5258a97a208d3c44551b854e510994f24683865d846c + date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 + deface (1.9.0) sha256=b6da77da3618efa4ec33474debc7e95f8b4d84775f34b9d13799d97f6aef3806 + devise (4.9.4) sha256=920042fe5e704c548aa4eb65ebdd65980b83ffae67feb32c697206bfd975a7f8 + devise-encryptable (0.2.0) sha256=9860caed9484030c438cfaf05831355c16c6a9612dcd1e12e84805850f7d09b6 + diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 + docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e + doorkeeper (5.8.2) sha256=a73d07aeaf590b1e7e2a35390446f23131c9f37bc0561653e514d3973f4d50d3 + dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5 + erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9 + factory_bot (6.5.6) sha256=12beb373214dccc086a7a63763d6718c49769d5606f0501e0a4442676917e077 + factory_bot_rails (6.5.1) sha256=d3cc4851eae4dea8a665ec4a4516895045e710554d2b5ac9e68b94d351bc6d68 + faraday (2.14.0) sha256=8699cfe5d97e55268f2596f9a9d5a43736808a943714e3d9a53e6110593941cd + faraday-http-cache (2.6.1) sha256=7772ae61c5fe1c0243452dec1f069b15bcc3304e9436e4f8545ccdb5963c4285 + faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c + ffaker (2.25.0) sha256=e485c5adf8195aac55662875b7f515469bca46d77b60d0e7d08db6861bcbec40 + ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068 + ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2 + ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668 + ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053 + ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f + ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5 + ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f + ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 + fiber-annotation (0.2.0) sha256=7abfadf1d119f508867d4103bf231c0354d019cc39a5738945dec2edadaf6c03 + fiber-local (1.1.0) sha256=c885f94f210fb9b05737de65d511136ea602e00c5105953748aa0f8793489f06 + fiber-storage (1.0.1) sha256=f48e5b6d8b0be96dac486332b55cee82240057065dc761c1ea692b2e719240e1 + friendly_id (5.5.1) sha256=e018f2b89bfc143276fee6d378a64792385cd4fddd3d4fce501f59ec19c06207 + friendly_id-mobility (1.0.5) sha256=8c0cf4d0a1358311db1b2dcc0e4c33077ae929c7e34749485268d066adbaf2e4 + gem-release (2.2.4) sha256=2f11124c1580c811507c3b47e875e420cf3ed792a98105b49df11971e6e94db3 + geocoder (1.8.6) sha256=e0ca1554b499f466de9b003f7dff70f89a5888761c2ca68ed9f86b6e5e24e74c + github_changelog_generator (1.16.4) sha256=21d2dfe41d50cf3a7ffe896774779d9d61da6aaf08d390f8ddff0dacbdf8a611 + globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11 + groupdate (6.7.0) sha256=beaa8d5bf3856814681914a1d4a20e77436a2214b85d0017dc2ea5c355fb6777 + hashdiff (1.2.1) sha256=9c079dbc513dfc8833ab59c0c2d8f230fa28499cc5efb4b8dd276cf931457cd1 + heroicon (1.0.0) sha256=e63a535a630d6fd3d99c0179d722753c8cd3478df1277eca7a4215c135b6e9cb + highline (3.1.2) sha256=67cbd34d19f6ef11a7ee1d82ffab5d36dfd5b3be861f450fc1716c7125f4bb4a + hightop (0.6.0) sha256=d3799d2232e4d0bc69bfd940e49832d66bcf18b7098be252a4fd65f1eb29b778 + i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 + i18n-tasks (1.1.2) sha256=4dcfba49e52a623f30661cb316cb80d84fbba5cb8c6d88ef5e02545fffa3637a + image_processing (1.14.0) sha256=754cc169c9c262980889bec6bfd325ed1dafad34f85242b5a07b60af004742fb + importmap-rails (2.2.3) sha256=7101be2a4dc97cf1558fb8f573a718404c5f6bcfe94f304bf1f39e444feeb16a + inline_svg (1.10.0) sha256=5b652934236fd9f8adc61f3fd6e208b7ca3282698b19f28659971da84bf9a10f + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + io-endpoint (0.17.1) sha256=e7bf943d89fdf83472b3fe3c06d7d290735b7e58bb968dcfa8c687a06ad11ee7 + io-event (1.14.2) sha256=b0a069190eafe86005c22f7464f744971b5bd82f153740d34e6ab49548d4f613 + io-stream (0.11.1) sha256=fa5f551fcff99581c1757b9d1cee2c37b124f07d2ca4f40b756a05ab9bd21b87 + irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806 + json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505 + jsonapi-rspec (0.0.11) sha256=995f1adb59b386cc36e3f6823c828df575167586937e3e42601914c4ee650082 + jsonapi-serializer (2.2.0) sha256=f8141ac6f0c1e17e8513df68f8341afe2d7bffc285841d7090bc07f07efb0029 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + launchy (3.1.1) sha256=72b847b5cc961589dde2c395af0108c86ff0119f42d4648d25b5440ebb10059e + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + local_time (3.0.3) sha256=c69a8974d993fdf6e60db02977ed23c070f203dcb3a1ff0de52ad3d2393f8303 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + loofah (2.25.0) sha256=df5ed7ac3bac6a4ec802df3877ee5cc86d027299f8952e6243b3dac446b060e6 + mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 + mail_form (1.11.0) sha256=54aaaf11b69e7e5bd4be220dfc80f2469bb809d6ed1f893b8d940f0b67232c5a + mapkick-rb (0.2.0) sha256=c70da2e1edc56da290ccab51fd932ee5b1c562fe9f7877de0333b5562937e28e + marcel (1.1.0) sha256=fdcfcfa33cc52e93c4308d40e4090a5d4ea279e160a7f6af988260fa970e0bee + matrix (0.4.3) sha256=a0d5ab7ddcc1973ff690ab361b67f359acbb16958d1dc072b8b956a286564c5b + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + metrics (0.15.0) sha256=61ded5bac95118e995b1bc9ed4a5f19bc9814928a312a85b200abbdac9039072 + mini_magick (5.3.1) sha256=29395dfd76badcabb6403ee5aff6f681e867074f8f28ce08d78661e9e4a351c4 + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb + mobility (1.3.2) sha256=32fbbb0e53118ef42de20daa6ac94dbb758c628874092eba311b968a1e1d757b + mobility-actiontext (1.1.1) sha256=98f8fb9f2d8aa49fce1814eefb2ad8060efdfb89167bc5bd864da0bdd858127d + mobility-ransack (1.2.2) sha256=8b480ce5bc4937abc37c17b9922d7e41b8a7064a3207b3a64e5aa71e0cb3332b + monetize (1.13.0) sha256=0c1f8ae28aa21bbf1a6d014138d9bb0a5ce756c1a99b8b7f7d409c258b01d3b3 + money (6.19.0) sha256=ec936fa1e42f2783719241ed9fd52725d0efa628f928feea1eb5c37d5de7daf3 + multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 + name_of_person (1.1.3) sha256=e12291250987ef79c413314f698f15d53e7a602c42231de99c276ef9585bc18c + net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 + net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6 + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1 + nokogiri (1.19.0-aarch64-linux-gnu) sha256=11a97ecc3c0e7e5edcf395720b10860ef493b768f6aa80c539573530bc933767 + nokogiri (1.19.0-aarch64-linux-musl) sha256=eb70507f5e01bc23dad9b8dbec2b36ad0e61d227b42d292835020ff754fb7ba9 + nokogiri (1.19.0-arm-linux-gnu) sha256=572a259026b2c8b7c161fdb6469fa2d0edd2b61cd599db4bbda93289abefbfe5 + nokogiri (1.19.0-arm-linux-musl) sha256=23ed90922f1a38aed555d3de4d058e90850c731c5b756d191b3dc8055948e73c + nokogiri (1.19.0-arm64-darwin) sha256=0811dfd936d5f6dd3f6d32ef790568bf29b2b7bead9ba68866847b33c9cf5810 + nokogiri (1.19.0-x86_64-darwin) sha256=1dad56220b603a8edb9750cd95798bffa2b8dd9dd9aa47f664009ee5b43e3067 + nokogiri (1.19.0-x86_64-linux-gnu) sha256=f482b95c713d60031d48c44ce14562f8d2ce31e3a9e8dd0ccb131e9e5a68b58c + nokogiri (1.19.0-x86_64-linux-musl) sha256=1c4ca6b381622420073ce6043443af1d321e8ed93cc18b08e2666e5bd02ffae4 + observer (0.1.2) sha256=d8a3107131ba661138d748e7be3dbafc0d82e732fffba9fccb3d7829880950ac + octokit (4.25.1) sha256=c02092ee82dcdfe84db0e0ea630a70d32becc54245a4f0bacfd21c010df09b96 + openssl (4.0.0) sha256=185711ed93d4e9c9a9db6efea7edb202dfe04f7d3692fbab988e3d84e498ee91 + orm_adapter (0.5.0) sha256=aa5d0be5d540cbb46d3a93e88061f4ece6a25f6e97d6a47122beb84fe595e9b9 + ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 + pagy (43.2.8) sha256=3d38376df4a9a7893361bb68825643896371707c4c49ef73acf1bd3b50af7562 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + paranoia (3.1.0) sha256=36574a46e8df663d0da7d9008e987b72a6a9eccee13c058b7094acc810e39f52 + parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 + phonelib (0.10.15) sha256=8e0c06acef2867632691d80b63d38438524cb0941b6c7da2551e00f91a5787b8 + polyglot (0.3.5) sha256=59d66ef5e3c166431c39cb8b7c1d02af419051352f27912f6a43981b3def16af + pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6 + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254 + protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91 + protocol-http (0.58.1) sha256=6d0694aa07cd51ff589c6219f9613c6827aebd5ffdf8fb8a0169254feb0f13fd + protocol-http1 (0.37.0) sha256=5bdd739e28792b341134596f6f5ab21a9d4b395f67bae69e153743eb0e69d123 + protocol-http2 (0.24.0) sha256=65327a019b7e36d2774e94050bf57a43bb60212775d2fcf02ae1d2ed4f01ef28 + protocol-url (0.4.0) sha256=64d4c03b6b51ad815ac6fdaf77a1d91e5baf9220d26becb846c5459dacdea9e1 + pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e + psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974 + public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + puma (7.2.0) sha256=bf8ef4ab514a4e6d4554cb4326b2004eba5036ae05cf765cfe51aba9706a72a8 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 + rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 + rails (8.1.2) sha256=5069061b23dfa8706b9f0159ae8b9d35727359103178a26962b868a680ba7d95 + rails-controller-testing (1.0.5) sha256=741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94 + rails-dom-testing (2.3.0) sha256=8acc7953a7b911ca44588bf08737bc16719f431a1cc3091a292bca7317925c1d + rails-html-sanitizer (1.6.2) sha256=35fce2ca8242da8775c83b6ba9c1bcaad6751d9eb73c1abaa8403475ab89a560 + rails-i18n (8.1.0) sha256=52d5fd6c0abef28d84223cc05647f6ae0fd552637a1ede92deee9545755b6cf3 + railties (8.1.2) sha256=1289ece76b4f7668fc46d07e55cc992b5b8751f2ad85548b7da351b8c59f8055 + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + ransack (4.4.1) sha256=6aeaac36fc19088570e10da1044e6cfd88c740e20f871b84566fd30e32b7a63d + rbs (3.10.2) sha256=bd8a5dc4c62f229f020146b61844a31f9c79e649449d212904a474eb79c846fc + rdoc (7.1.0) sha256=494899df0706c178596ca6e1d50f1b7eb285a9b2aae715be5abd742734f17363 + regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb + responders (3.2.0) sha256=89c2d6ac0ae16f6458a11524cae4a8efdceba1a3baea164d28ee9046bd3df55a + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rspec-activemodel-mocks (1.3.0) sha256=b51b111b726370a20a2103a8a6851296783a70d2b0bd0287bfa24d293f58d76e + rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.7) sha256=0979034e64b1d7a838aaaddf12bf065ea4dc40ef3d4c39f01f93ae2c66c62b1c + rspec-rails (8.0.2) sha256=113139a53f5d068d4f48d1c29ad5f982013ed9b0daa69d7f7b266eda5d433ace + rspec-retry (0.6.2) sha256=6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858 + rspec-support (3.13.6) sha256=2e8de3702427eab064c9352fe74488cc12a1bfae887ad8b91cba480ec9f8afb2 + rspec_junit_formatter (0.6.0) sha256=40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15 + rubocop (1.84.0) sha256=88dec310153bb685a879f5a7cdb601f6287b8f0ee675d9dc63a17c7204c4190a + rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 + rubocop-rails (2.34.3) sha256=10d37989024865ecda8199f311f3faca990143fbac967de943f88aca11eb9ad2 + rubocop-rails-omakase (1.1.0) sha256=2af73ac8ee5852de2919abbd2618af9c15c19b512c4cfc1f9a5d3b6ef009109d + rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2 + ruby-lsp (0.26.5) sha256=19272659139b292a81a700d78e1b4d8988c4812e96b54fd6c30a21ce5e82b189 + ruby-oembed (0.18.1) sha256=877b87b3d98e8137599044277fdb82a5536973bd9df68a93129163b781ae3a5f + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + ruby-vips (2.3.0) sha256=e685ec02c13969912debbd98019e50492e12989282da5f37d05f5471442f5374 + rubyzip (2.4.1) sha256=8577c88edc1fde8935eb91064c5cb1aef9ad5494b940cf19c775ee833e075615 + safely_block (0.5.0) sha256=782c342bc400a79c1233c40cf8c379da6116c6cfd1d7c1f17f0ef2ef11090103 + sawyer (0.9.3) sha256=0d0f19298408047037638639fe62f4794483fb04320269169bd41af2bdcf5e41 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + selenium-webdriver (4.10.0) sha256=a322af38f9a8966a6c3ab85c365b08c5556cdef72f577905b2b42469faee9d43 + simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5 + simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246 + simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 + spree (5.3.0) sha256=5455d28c79e96b76c597a5787d301132b6ee7b830c95de77c9b15a36af2c9fb1 + spree-spl (2.0.0) + spree_admin (5.3.0) sha256=86d2492c3c98efcc9d6ec099594eff23251f4aff1154eb266a3d2510524d4559 + spree_api (5.3.0) sha256=b3ef192c1f2453770d20ef5e1dcb38568b7b0a128ddde38bdca7c2a138dc5756 + spree_auth_devise (4.6.3) sha256=5eeada77570f5ab335a9c6c150d7cdaee39203ce43b70ac24d2ffb195952ed6e + spree_cli (5.3.0) sha256=a5cfd2d5bde7f120f6631bb59c8d337d1a29a93d3523c02ab0febf93511d1dac + spree_core (5.3.0) sha256=e96ad7492b758fe15261d4fe9a15e1149034bf1b34844acad0c0383e06d42889 + spree_dev_tools (0.5.2) sha256=faa8bda07eb785e066032e5527663292bbe0dfab653fc06c61d56798dd4deea7 + spree_extension (0.1.0) sha256=b648327f4787295e051be4ea0c0a47baec47c2e245bca9c93ecf73605fc3a051 + spree_page_builder (5.3.0) sha256=1501377b720c29ffd2adfd8b195221580d8023b22552cc34d99aa899112bae8e + spree_storefront (5.3.0) sha256=f7db814f8ac43390660bc6d987bf67e97d48ca27c0502fd93b9115bd7d2b63cd + sprockets (4.2.2) sha256=761e5a49f1c288704763f73139763564c845a8f856d52fba013458f8af1b59b1 + sprockets-rails (3.5.2) sha256=a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e + sqlite3 (2.9.0-aarch64-linux-gnu) sha256=cfe1e0216f46d7483839719bf827129151e6c680317b99d7b8fc1597a3e13473 + sqlite3 (2.9.0-aarch64-linux-musl) sha256=56a35cb2d70779afc2ac191baf2c2148242285ecfed72f9b021218c5c4917913 + sqlite3 (2.9.0-arm-linux-gnu) sha256=a19a21504b0d7c8c825fbbf37b358ae316b6bd0d0134c619874060b2eef05435 + sqlite3 (2.9.0-arm-linux-musl) sha256=fca5b26197c70e3363115d3faaea34d7b2ad9c7f5fa8d8312e31b64e7556ee07 + sqlite3 (2.9.0-arm64-darwin) sha256=a917bd9b84285766ff3300b7d79cd583f5a067594c8c1263e6441618c04a6ed3 + sqlite3 (2.9.0-x86_64-darwin) sha256=59fe51baa3cb33c36d27ce78b4ed9360cd33ccca09498c2ae63850c97c0a6026 + sqlite3 (2.9.0-x86_64-linux-gnu) sha256=72fff9bd750070ba3af695511ba5f0e0a2d8a9206f84869640b3e99dfaf3d5a5 + sqlite3 (2.9.0-x86_64-linux-musl) sha256=ef716ba7a66d7deb1ccc402ac3a6d7343da17fac862793b7f0be3d2917253c90 + state_machines (0.100.4) sha256=dd4e555ebb061569dd8fe18a5f39b51d10be6306b89a0c315a9697671d752565 + state_machines-activemodel (0.101.0) sha256=6798c6bf5aa4be2b1a00ca633949c999ebee7a148bd4ea8f6858b189e2cdf72d + state_machines-activerecord (0.100.0) sha256=b2213f74f3f32c6d92de5139e8898bc64a0ffb3f048df7d950ce27e28384beb5 + stimulus-rails (1.3.4) sha256=765676ffa1f33af64ce026d26b48e8ffb2e0b94e0f50e9119e11d6107d67cb06 + stringex (2.8.6) sha256=c7b382d2b2a47a1e1646f256df201c48d487d6296fbb289d76802f67f5e929c4 + stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1 + tailwindcss-rails (4.4.0) sha256=efa2961351a52acebe616e645a81a30bb4f27fde46cc06ce7688d1cd1131e916 + tailwindcss-ruby (4.1.18) sha256=b62fad5b00494e92987ee319dfb5c5ad272f0ed93649963d62f08d2ba0f03fa7 + tailwindcss-ruby (4.1.18-aarch64-linux-gnu) sha256=e10f9560bccddbb4955fd535b3bcc8c7071a7df07404dd473a23fa791ec4e46b + tailwindcss-ruby (4.1.18-aarch64-linux-musl) sha256=3c8426674718a2c98a0649c825ac0b3286ff52acd0b4052d7d19126cd74904f3 + tailwindcss-ruby (4.1.18-arm64-darwin) sha256=f940531d5a030c566d3d616004235bcd4c361abdd328f7d6c7e3a953a32e0155 + tailwindcss-ruby (4.1.18-x86_64-darwin) sha256=6a82115b606a6f748c600c666a19c16ee28f5736217af8d0c20cee5abe1ce2f7 + tailwindcss-ruby (4.1.18-x86_64-linux-gnu) sha256=e0a2220163246fe0126c5c5bafb95bc6206e7d21fce2a2878fd9c9a359137534 + tailwindcss-ruby (4.1.18-x86_64-linux-musl) sha256=d957cf545b09d2db7eb6267450cc1fc589e126524066537a0c4d5b99d701f4b2 + terminal-table (4.0.0) sha256=f504793203f8251b2ea7c7068333053f0beeea26093ec9962e62ea79f94301d2 + thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73 + timecop (0.9.10) sha256=12ba45ce57cdcf6b1043cb6cdffa6381fd89ce10d369c28a7f6f04dc1b0cd8eb + timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af + tinymce-rails (6.8.6.1) sha256=b249fccfb300d8cdb361a443e859d6b45ec6d7bbd1466817008ee0af2a3d516c + traces (0.18.2) sha256=80f1649cb4daace1d7174b81f3b3b7427af0b93047759ba349960cb8f315e214 + tracking_number (2.4.0) sha256=2a4c6b39cbdfc8326c234626556da1e269c8dfe33478786bea93461331c247ff + tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f + turbo-rails (2.0.21) sha256=02070ea29fd11d8c1a07d9d7be980729a20e94e39b8c6c819f690f7959216bc7 + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unaccent (0.4.0) sha256=d9278230016edc5317c053f8e84c1e1dea6827dec028e5481e2294a4e11e7333 + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 + useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844 + validates_zipcode (0.5.4) sha256=fc2a064bed9303fa2fda36f730367a4d5d95a8f4c74baa1aae2b80119da8cc0f + wannabe_bool (0.7.1) sha256=838ef671066868424de888fb22eeae57c7012709aabd5d17141ea6fea964c61f + warden (1.2.9) sha256=46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0 + webdrivers (5.3.1) sha256=d7d5531fbc3c44b6a2a7710e3e6c5edc54f35c68af20017309e3eccf15ec4aa5 + webmock (3.26.1) sha256=4f696fb57c90a827c20aadb2d4f9058bbff10f7f043bd0d4c3f58791143b1cd7 + websocket (1.2.11) sha256=b7e7a74e2410b5e85c25858b26b3322f29161e300935f70a0e0d3c35e0462737 + websocket-driver (0.8.0) sha256=ed0dba4b943c22f17f9a734817e808bc84cdce6a7e22045f5315aa57676d4962 + websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 + xpath (3.2.0) sha256=6dfda79d91bb3b949b947ecc5919f042ef2f399b904013eb3ef6d20dd3a4082e + yaml (0.4.0) sha256=240e69d1e6ce3584d6085978719a0faa6218ae426e034d8f9b02fb54d3471942 + zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b + BUNDLED WITH 2.7.2 diff --git a/app/controllers/spl/spree/storefront/checkout_controller_decorator.rb b/app/controllers/spl/spree/storefront/checkout_controller_decorator.rb index aa757d8..275d778 100644 --- a/app/controllers/spl/spree/storefront/checkout_controller_decorator.rb +++ b/app/controllers/spl/spree/storefront/checkout_controller_decorator.rb @@ -4,20 +4,45 @@ module Spl module Spree module Storefront module CheckoutControllerDecorator + include ErrorHandlingHelper include BooleanHelper def self.prepended(base) - base.before_action :load_user_coupons base.before_action :promotion_switcher + base.before_action :load_user_coupons, except: %i[activate_coupon deactivate_coupon] base.after_action :perform_update_sparta_state_job, only: %i[confirm complete] end - private + def activate_coupon + Spl::Coupons::ActivateCouponService.new(@order.user, @order.store, params[:coupon_code]).call + load_user_coupons + rescue StandardError => e + handle_spl_error(e) + raise e + ensure + respond_to do |format| + format.turbo_stream + format.html { redirect_to checkout_path } + end + end - def load_user_coupons - @coupons = Spl::GetCouponsService.new(@order.user, @order.store).call + def deactivate_coupon + Spl::Coupons::DeactivateCouponService + .new(@order.user, @order.store, params[:coupon_code]) + .call + load_user_coupons + rescue StandardError => e + handle_spl_error(e) + raise e + ensure + respond_to do |format| + format.turbo_stream + format.html { redirect_to checkout_path } + end end + private + def promotion_switcher PromotionSwitcherService.new(@order, checkout_state_allowed?).call end @@ -34,6 +59,13 @@ def perform_update_sparta_state_job UpdateSpartaStateJob.perform_later(@order.token, 'C', @order.number, @order.store) end end + + def load_user_coupons + @coupons = Spl::Coupons::GetCouponsService.new(@order.user, @order.store).call + rescue StandardError => e + handle_spl_error(e) + raise e + end end end end diff --git a/app/controllers/spl/spree/storefront/profile_controller_decorator.rb b/app/controllers/spl/spree/storefront/profile_controller_decorator.rb index e7fc097..c12a1e8 100644 --- a/app/controllers/spl/spree/storefront/profile_controller_decorator.rb +++ b/app/controllers/spl/spree/storefront/profile_controller_decorator.rb @@ -6,6 +6,7 @@ module Storefront module ProfileControllerDecorator include BooleanHelper include ProfileControllerHelper + include ErrorHandlingHelper def self.prepended(base) base.before_action :validate_spl_no_card, only: :update @@ -128,9 +129,37 @@ def clear_errors try_spree_current_user.errors.clear end - def assign_card_number(user, store, params) - Spl::LoginAccountService.new(user, store, params).call - AssignSpartaCardNumberService.new(user, store).call + def render_login_code_error + render turbo_stream: turbo_stream.replace( + 'loyalty_connect_form', + partial: 'spl/loyalty_connect_form', + locals: { user: try_spree_current_user } + ), + status: :unprocessable_content + end + + def render_login_code_success(phone) + render turbo_stream: turbo_stream.replace( + 'loyalty_connect_form', + partial: 'spl/otp_code_form', + locals: { + user: try_spree_current_user, + phone_e164: phone.respond_to?(:e164) ? phone.e164 : nil + } + ), + status: :ok + end + + def render_connect_loyalty_account_error(phone) + render turbo_stream: turbo_stream.replace( + 'otp_code_form', + partial: 'spl/otp_code_form', + locals: { + user: try_spree_current_user, + phone_e164: phone.respond_to?(:e164) ? phone.e164 : nil + } + ), + status: :unprocessable_content end def send_otp(phone, store) @@ -152,6 +181,11 @@ def handle_spl_error(error) try_spree_current_user.errors.add(:base, msg) end + def assign_card_number(user, store, params) + Spl::LoginAccountService.new(user, store, params).call + AssignSpartaCardNumberService.new(user, store).call + end + def login_code_params params.require(:user).permit(:phone, :accept_yc_terms) end diff --git a/app/helpers/error_handling_helper.rb b/app/helpers/error_handling_helper.rb new file mode 100644 index 0000000..9ee48c6 --- /dev/null +++ b/app/helpers/error_handling_helper.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module ErrorHandlingHelper + # Parses and translate occurred error, then adds it to user errors. + # Dedicated for storefront controllers. + # @param [StandardError] + def handle_spl_error(error) + payload = Spl::ErrorPayloadParser.parse(error.message) || error + msg = Spl::ErrorTranslator.translate(payload) + + clear_errors + try_spree_current_user.errors.add(:base, msg) + end + + def clear_errors + try_spree_current_user.errors.clear + end + + def token_expired?(err_msg) + err_msg == 'TOKEN_EXPIRED' + end +end diff --git a/app/helpers/login_check_helper.rb b/app/helpers/login_check_helper.rb index dd9811a..7c23d5f 100644 --- a/app/helpers/login_check_helper.rb +++ b/app/helpers/login_check_helper.rb @@ -4,9 +4,7 @@ module LoginCheckHelper # Checks if user is logged to SPL basing on local information # @param user [Spree::User] # @return [true, false] - def self.logged?(user) - return false unless user&.private_metadata&.fetch('spl_access_token', nil) - - true + def logged_user?(user) + user&.private_metadata&.fetch('spl_access_token', nil).present? end end diff --git a/app/helpers/spl_service_helper.rb b/app/helpers/spl_service_helper.rb new file mode 100644 index 0000000..30f7e56 --- /dev/null +++ b/app/helpers/spl_service_helper.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module SplServiceHelper + def send_request(url, body) + Spl::SendRequestService.new(url, body).call + end + + # Refreshes user private token to keep possible + # using customer oriented endpoints + # @param [user: Spree::User] + def refresh_user_token(user, store) + return if user.private_metadata.nil? + return if user.private_metadata['spl_refresh_token'].nil? + + response = Spl::OauthTokenService.new(DateTime.current, store).refresh_token(user.private_metadata['spl_refresh_token']) + + user.update!(private_metadata: { spl_access_token: response['access_token'], + spl_refresh_token: response['refresh_token'] }) + end + + def token_refresh_needed(response_body, retry_counter, user, store) + token_expired?(response_body['errorCode']) && retry_counter < 1 && refresh_user_token(user, store) + end +end diff --git a/app/services/apply_sparta_discount_service.rb b/app/services/apply_sparta_discount_service.rb index 8847b52..83bf018 100644 --- a/app/services/apply_sparta_discount_service.rb +++ b/app/services/apply_sparta_discount_service.rb @@ -10,7 +10,7 @@ def initialize(response, order) @response = response end - def call # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity + def call # rubocop:disable Metrics/AbcSize return unless response_valid? line_items.each do |line_item| diff --git a/app/services/spl/coupons/activate_coupon_service.rb b/app/services/spl/coupons/activate_coupon_service.rb new file mode 100644 index 0000000..5d2f2c7 --- /dev/null +++ b/app/services/spl/coupons/activate_coupon_service.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'json' + +module Spl + module Coupons + class ActivateCouponService + class ActivateCouponServiceError < StandardError; end + include SplServiceHelper + include ErrorHandlingHelper + include LoginCheckHelper + + def initialize(user, store, coupon_code) + @store = store + @activate_coupons_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).coupon_activate) + @user = user + @coupon_code = coupon_code + @retry_counter = 0 + end + + def call + return unless @user.present? && @user.private_metadata.present? + return unless logged_user?(@user) + + response = send_request(@activate_coupons_url, body) + response_body = JSON.parse(response.body) + Rails.logger.debug response_body + raise ActivateCouponServiceError, response_body['msg'] if response_body['errorCode'] != '0' + + response_body['response'] + rescue ActivateCouponServiceError => e + raise e unless token_refresh_needed(response_body, @retry_counter, @user, @store) + + @retry_counter += 1 + retry + end + + private + + def body + { + context: { + prgCode: @store.private_metadata['spl_prg_code'], + oauthToken: @user.private_metadata['spl_access_token'] + }, + couponCode: @coupon_code + } + end + end + end +end diff --git a/app/services/spl/coupons/deactivate_coupon_service.rb b/app/services/spl/coupons/deactivate_coupon_service.rb new file mode 100644 index 0000000..d5ee195 --- /dev/null +++ b/app/services/spl/coupons/deactivate_coupon_service.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'json' + +module Spl + module Coupons + class DeactivateCouponService + class DeactivateCouponServiceError < StandardError; end + include SplServiceHelper + include ErrorHandlingHelper + include LoginCheckHelper + + def initialize(user, store, coupon_code) + @store = store + @deactivate_coupons_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).coupon_deactivate) + @user = user + @coupon_code = coupon_code + @retry_counter = 0 + end + + def call + return unless @user.present? && @user.private_metadata.present? + return unless logged_user?(@user) + + response = send_request(@deactivate_coupons_url, body) + response_body = JSON.parse(response.body) + Rails.logger.debug response_body + raise DeactivateCouponServiceError, response_body['msg'] if response_body['errorCode'] != '0' + + response_body['response'] + rescue DeactivateCouponServiceError => e + raise e unless token_refresh_needed(response_body, @retry_counter, @user, @store) + + @retry_counter += 1 + retry + end + + private + + def body + { + context: { + prgCode: @store.private_metadata['spl_prg_code'], + oauthToken: @user.private_metadata['spl_access_token'] + }, + couponCode: @coupon_code + } + end + end + end +end diff --git a/app/services/spl/coupons/get_coupons_service.rb b/app/services/spl/coupons/get_coupons_service.rb new file mode 100644 index 0000000..1d7193a --- /dev/null +++ b/app/services/spl/coupons/get_coupons_service.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'json' + +module Spl + module Coupons + class GetCouponsService + class SplGetCouponError < StandardError; end + include SplServiceHelper + include ErrorHandlingHelper + include LoginCheckHelper + + def initialize(user, store) + @store = store + @find_coupons_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).coupon_find) + @user = user + @retry_counter = 0 + end + + def call + return unless @user.present? && @user.private_metadata.present? + return unless logged_user?(@user) + + response = send_request(@find_coupons_url, body) + response_body = JSON.parse(response.body) + Rails.logger.debug response_body + raise SplGetCouponError, response_body['msg'] if response_body['errorCode'] != '0' + + filtered_coupons(response_body) + rescue SplGetCouponError => e + raise e unless token_refresh_needed(response_body, @retry_counter, @user, @store) + + @retry_counter += 1 + retry + end + + private + + def body + { + context: { + prgCode: @store.private_metadata['spl_prg_code'], + oauthToken: @user.private_metadata['spl_access_token'] + }, + withArchival: true + } + end + + def filtered_coupons(response_body) + response_body['response']&.filter do |coupon| + active?(coupon) + end + end + + def active?(coupon) + coupon['used'] != true && coupon['usageTemporaryBlocked'] != true && correct_time?(coupon['expirationDate']) && + coupon['usageDisabled'] != true + end + + def correct_time?(date) + return Time.zone.parse(date).future? unless date.nil? + + true + end + end + end +end diff --git a/app/services/spl/get_coupons_service.rb b/app/services/spl/get_coupons_service.rb deleted file mode 100644 index e4bdceb..0000000 --- a/app/services/spl/get_coupons_service.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'json' - -module Spl - class GetCouponsService - include LoginCheckHelper - - class SplGetCouponError < StandardError; end - - def initialize(user, store) - @store = store - @find_coupons_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).coupon_find) - @user = user - end - - def call - return unless logged_user? - - body = prepare_body - response = send_request(@find_coupons_url, body) - response_body = JSON.parse(response.body) - Rails.logger.debug response_body - raise SplGetCouponError, response_body['msg'] if response_body['errorCode'] != '0' - - response_body['response'] - end - - private - - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - - def prepare_body - { - context: { - prgCode: @store.private_metadata['spl_prg_code'], - oauthToken: @user.private_metadata['spl_access_token'] - } - } - end - - def logged_user? - LoginCheckHelper.logged?(@user) - end - end -end diff --git a/app/services/spl/login_account_service.rb b/app/services/spl/login_account_service.rb index 0e156da..5308f10 100644 --- a/app/services/spl/login_account_service.rb +++ b/app/services/spl/login_account_service.rb @@ -5,6 +5,7 @@ module Spl class LoginAccountService class SplLoginAccountError < StandardError; end + include SplServiceHelper def initialize(user, store, params) @login_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).login) @@ -29,10 +30,6 @@ def call private - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - def prepare_login_body { context: { @@ -60,10 +57,10 @@ def generate_login def get_access_token(access_token) token_body = Spl::OauthTokenService.new(DateTime.current, @store).authorization_code_token(access_token) - add_loyalty_tokents_to_user(token_body['accessToken'], token_body['refreshToken']) + add_loyalty_tokens_to_user(token_body['accessToken'], token_body['refreshToken']) end - def add_loyalty_tokents_to_user(access_token, refresh_token) + def add_loyalty_tokens_to_user(access_token, refresh_token) @user.update!(private_metadata: { spl_access_token: access_token, spl_refresh_token: refresh_token }) end diff --git a/app/services/spl/me_service.rb b/app/services/spl/me_service.rb index 767441b..7807320 100644 --- a/app/services/spl/me_service.rb +++ b/app/services/spl/me_service.rb @@ -4,9 +4,10 @@ module Spl class MeService - include LoginCheckHelper - class SplMeError < StandardError; end + include SplServiceHelper + include ErrorHandlingHelper + include LoginCheckHelper def initialize(user, store) @me_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).me) @@ -15,24 +16,26 @@ def initialize(user, store) end def call - return unless logged_user? + return unless @user.present? && @user.private_metadata.present? + return unless logged_user?(@user) - body = prepare_me_body + retry_counter ||= 0 response = send_request(@me_url, body) response_body = JSON.parse(response.body) Rails.logger.debug response_body raise SplMeError, response_body if response_body['errorCode'] != '0' response_body + rescue SplMeError => e + raise e unless token_refresh_needed(response_body, @retry_counter, @user, @store) + + retry_counter += 1 + retry end private - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - - def prepare_me_body + def body { context: { prgCode: @env['spl_prg_code'], @@ -40,9 +43,5 @@ def prepare_me_body } } end - - def logged_user? - LoginCheckHelper.logged?(@user) - end end end diff --git a/app/services/spl/oauth_token_service.rb b/app/services/spl/oauth_token_service.rb index f59b63f..3bcea97 100644 --- a/app/services/spl/oauth_token_service.rb +++ b/app/services/spl/oauth_token_service.rb @@ -5,6 +5,7 @@ module Spl class OauthTokenService class OauthTokenError < StandardError; end + include SplServiceHelper def initialize(date, store) @date = date.to_i * 1000 @@ -32,12 +33,18 @@ def authorization_code_token(auth_code) response_body['response'] end - private + def refresh_token(token) + body = prepare_refresh_token_body(token) + response = send_request(@token_url, body) + response_body = JSON.parse(response.body) + + raise OauthTokenError, response_body['msg'] if response_body['errorCode'] != '0' - def send_request(url, body) - Spl::SendRequestService.new(url, body).call + response_body['response'] end + private + def prepare_oauth_token_body_with_signature { context: { @@ -63,6 +70,18 @@ def prepare_oauth_token_body_with_oauth_code(auth_code) } end + def prepare_refresh_token_body(token) + { + context: { + prgCode: @env['spl_prg_code'] + }, + apiUser: @env['spl_api_user'], + apiToken: @env['spl_api_token'], + refreshToken: token, + grantType: 'refresh_token' + } + end + def generate_signature Spl::ClientSignatureService.new(@date, @env['spl_api_token'], diff --git a/app/services/spl/register_account_service.rb b/app/services/spl/register_account_service.rb index 5682d80..51d5743 100644 --- a/app/services/spl/register_account_service.rb +++ b/app/services/spl/register_account_service.rb @@ -5,6 +5,7 @@ module Spl class RegisterAccountService class SplRegisterAccountError < StandardError; end + include SplServiceHelper def initialize(user, store, params) @register_url = URI.parse(Spl::UrlCreatorService.new(store.private_metadata['spl_url']).register) @@ -30,10 +31,6 @@ def call private - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - def prepare_registration_body(access_token) # rubocop:disable Metrics/MethodLength accept_yc_terms = @user.public_metadata['accept_yc_terms'] { diff --git a/app/services/spl/request_otp_service.rb b/app/services/spl/request_otp_service.rb index a210b8c..d8aed32 100644 --- a/app/services/spl/request_otp_service.rb +++ b/app/services/spl/request_otp_service.rb @@ -5,6 +5,7 @@ module Spl class RequestOtpService class SplRequestOtpError < StandardError; end + include SplServiceHelper def initialize(date, store, params) @date = date.to_i * 1000 @@ -30,10 +31,6 @@ def call private - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - def prepare_sms_otp_body(access_token) { context: { diff --git a/app/services/spl/send_otp_service.rb b/app/services/spl/send_otp_service.rb index a2f5fda..b1e77e7 100644 --- a/app/services/spl/send_otp_service.rb +++ b/app/services/spl/send_otp_service.rb @@ -5,6 +5,7 @@ module Spl class SendOtpService class SplSendOtpError < StandardError; end + include SplServiceHelper def initialize(date, mobile_country, phone_number, store) @date = date.to_i * 1000 @@ -26,10 +27,6 @@ def call private - def send_request(url, body) - Spl::SendRequestService.new(url, body).call - end - def prepare_sms_otp_body { context: { diff --git a/app/services/spl/sparta_loyalty_service.rb b/app/services/spl/sparta_loyalty_service.rb index a765a15..df86506 100644 --- a/app/services/spl/sparta_loyalty_service.rb +++ b/app/services/spl/sparta_loyalty_service.rb @@ -7,6 +7,7 @@ module Spl class SpartaLoyaltyService class SplSendRequestError < StandardError; end + include SplServiceHelper def initialize(order_token, card_number, line_items, date, products, check_only, store) @order_token = order_token @@ -22,7 +23,7 @@ def initialize(order_token, card_number, line_items, date, products, check_only, def call Rails.logger.debug 'SPL LOYALTY SERVICE START' basket_body = prepare_basket_body - response = send_request(basket_body) + response = send_request(@url, basket_body) return unless response.is_a?(Net::HTTPSuccess) response_body = JSON.parse(response.body) @@ -35,10 +36,6 @@ def call private - def send_request(body) - Spl::SendRequestService.new(@url, body).call - end - def prepare_basket_body # rubocop:disable Metrics/MethodLength { ver: 4, diff --git a/app/services/spl/url_creator_service.rb b/app/services/spl/url_creator_service.rb index af94517..6f0195d 100644 --- a/app/services/spl/url_creator_service.rb +++ b/app/services/spl/url_creator_service.rb @@ -30,6 +30,14 @@ def coupon_find "#{coupon_base}/find" end + def coupon_activate + "#{coupon_base}/activate" + end + + def coupon_deactivate + "#{coupon_base}/deactivate" + end + ## Authentication and Authorization def check_card diff --git a/app/services/spl/validate_card_service.rb b/app/services/spl/validate_card_service.rb index 8f52ad4..fcdea46 100644 --- a/app/services/spl/validate_card_service.rb +++ b/app/services/spl/validate_card_service.rb @@ -47,6 +47,7 @@ def check_for_errors(response_body) 'status') != 'A' end + # @todo: refactor this and build_post_request method usages to use Spl::SendRequestService instead def verify_card_request url = URI.parse(Spl::UrlCreatorService.new(@store.private_metadata['spl_url']).check_card) http = Net::HTTP.new(url.host, url.port) diff --git a/app/views/spree/checkout/_spl_coupons.html.erb b/app/views/spree/checkout/_spl_coupons.html.erb index f163963..f435677 100644 --- a/app/views/spree/checkout/_spl_coupons.html.erb +++ b/app/views/spree/checkout/_spl_coupons.html.erb @@ -1,6 +1,32 @@ -