snf_core 0.2.8 → 0.2.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/app/controllers/concerns/common.rb +0 -0
- data/app/controllers/concerns/pagination.rb +0 -0
- data/app/controllers/snf_core/application_controller.rb +33 -0
- data/app/controllers/snf_core/auth_controller.rb +70 -0
- data/app/jobs/snf_core/application_job.rb +0 -0
- data/app/mailers/snf_core/application_mailer.rb +0 -0
- data/app/mailers/snf_core/auth_mailer.rb +13 -0
- data/app/models/snf_core/address.rb +0 -0
- data/app/models/snf_core/application_record.rb +0 -0
- data/app/models/snf_core/business.rb +0 -0
- data/app/models/snf_core/business_document.rb +15 -15
- data/app/models/snf_core/category.rb +0 -0
- data/app/models/snf_core/customer_group.rb +0 -0
- data/app/models/snf_core/delivery_order.rb +42 -0
- data/app/models/snf_core/group.rb +0 -0
- data/app/models/snf_core/order.rb +68 -0
- data/app/models/snf_core/order_item.rb +30 -0
- data/app/models/snf_core/product.rb +0 -0
- data/app/models/snf_core/role.rb +8 -0
- data/app/models/snf_core/store.rb +0 -0
- data/app/models/snf_core/store_inventory.rb +0 -0
- data/app/models/snf_core/user.rb +18 -18
- data/app/models/snf_core/user_role.rb +6 -0
- data/app/models/snf_core/wallet.rb +0 -0
- data/app/services/snf_core/token_service.rb +16 -0
- data/app/views/layouts/snf_core/mailer.html.erb +64 -0
- data/app/views/layouts/snf_core/mailer.text.erb +1 -0
- data/app/views/snf_core/auth_mailer/reset_password.html.erb +10 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20250226042622_create_snf_core_users.rb +13 -14
- data/db/migrate/20250226064444_create_snf_core_categories.rb +0 -0
- data/db/migrate/20250226080323_create_snf_core_businesses.rb +0 -0
- data/db/migrate/20250226102931_create_snf_core_business_documents.rb +0 -0
- data/db/migrate/20250226110217_create_snf_core_addresses.rb +0 -0
- data/db/migrate/20250226115215_create_snf_core_stores.rb +0 -0
- data/db/migrate/20250226181007_create_snf_core_products.rb +0 -0
- data/db/migrate/20250226190000_create_snf_core_store_inventories.rb +0 -0
- data/db/migrate/20250226192104_create_snf_core_groups.rb +0 -0
- data/db/migrate/20250226193938_create_snf_core_customer_groups.rb +0 -0
- data/db/migrate/20250227075048_create_snf_core_wallets.rb +0 -0
- data/db/migrate/20250227102833_modify_store_inventories.rb +0 -0
- data/db/migrate/20250305165926_create_snf_core_orders.rb +12 -0
- data/db/migrate/20250305170248_create_snf_core_order_items.rb +13 -0
- data/db/migrate/20250305201008_create_snf_core_delivery_orders.rb +15 -0
- data/db/migrate/20250305232529_create_snf_core_roles.rb +9 -0
- data/db/migrate/20250305232530_create_snf_core_user_roles.rb +10 -0
- data/db/migrate/20250306074713_add_password_fields_to_snf_core_users.rb +7 -0
- data/lib/snf_core/engine.rb +0 -0
- data/lib/snf_core/version.rb +1 -1
- data/lib/snf_core.rb +0 -0
- data/lib/tasks/snf_core_tasks.rake +0 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/dev +2 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +20 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +86 -0
- data/spec/dummy/config/environments/production.rb +86 -0
- data/spec/dummy/config/environments/test.rb +53 -0
- data/spec/dummy/config/initializers/cors.rb +16 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/locales/en.yml +31 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/storage.yml +38 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/db/migrate/20250226123213_create_active_storage_tables.active_storage.rb +57 -0
- data/spec/dummy/db/schema.rb +242 -0
- data/spec/dummy/log/development.log +3026 -0
- data/spec/dummy/log/test.log +133760 -0
- data/spec/dummy/spec/fixtures/files/sample.pdf +0 -0
- data/spec/dummy/tmp/letter_opener/1741263210_267596_73bfefe/rich.html +142 -0
- data/spec/dummy/tmp/letter_opener/1741263645_7876108_3edd95c/rich.html +132 -0
- data/spec/dummy/tmp/letter_opener/1741263812_8855171_0bf8e2b/rich.html +132 -0
- data/spec/dummy/tmp/local_secret.txt +1 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/dummy/tmp/storage/05/zb/05zbh3dr63t1ktnsxkwk2ugbglbu +0 -0
- data/spec/dummy/tmp/storage/0u/er/0uerkm5uy46p3lvg18c7ond00lih +0 -0
- data/spec/dummy/tmp/storage/13/1y/131yod70wqijazn3ix829yvuuvge +0 -0
- data/spec/dummy/tmp/storage/16/na/16na9nc1z98jt6fyn3axj3bhudes +0 -0
- data/spec/dummy/tmp/storage/17/wb/17wbd1yhh3pyg3j1sko570vsjnpq +0 -0
- data/spec/dummy/tmp/storage/1e/s9/1es9g1a309tf4bs04mr0i70usjz1 +0 -0
- data/spec/dummy/tmp/storage/1j/tj/1jtjythzzcpbajktrsn08af3x66m +0 -0
- data/spec/dummy/tmp/storage/1t/oy/1toyz0i6f9u5xexr4cpwttr04ood +0 -0
- data/spec/dummy/tmp/storage/1v/u3/1vu3btk2ukaxgp84qfmk5izonqmi +0 -0
- data/spec/dummy/tmp/storage/1x/i3/1xi33eqr5ipoaz0upakb8yy7qc4o +0 -0
- data/spec/dummy/tmp/storage/22/xs/22xscg5bqqtdykdaxrbr388lxkmf +0 -0
- data/spec/dummy/tmp/storage/24/69/2469t9kpepg4fd8ki960h025li0b +0 -0
- data/spec/dummy/tmp/storage/2a/0u/2a0uyihfk1wn5c1fuz09unocwy2m +0 -0
- data/spec/dummy/tmp/storage/2e/f9/2ef9j9go5h1v9ain8zq8m9zpjsf3 +0 -0
- data/spec/dummy/tmp/storage/2i/e3/2ie3ve4rajer9sx5zf6r45b3r9ar +0 -0
- data/spec/dummy/tmp/storage/2n/56/2n569vuf39piqdtbtbxsztn3r6kl +0 -0
- data/spec/dummy/tmp/storage/2o/te/2ote6co29576cnoptsem3lhupuxy +0 -0
- data/spec/dummy/tmp/storage/32/ur/32ur9eb5d0h01m2oe9kc5avpm31u +0 -0
- data/spec/dummy/tmp/storage/35/ov/35ovg8m7ij4fjqy3v4bh28e5hld2 +0 -0
- data/spec/dummy/tmp/storage/37/x2/37x2up33wqtrua85c089e6ltr49p +0 -0
- data/spec/dummy/tmp/storage/3i/8d/3i8dbcb1dk9ri0kumm3th8wo61gc +0 -0
- data/spec/dummy/tmp/storage/3u/jh/3ujhd5drl4t2nfbqw7ij2jzijxn1 +0 -0
- data/spec/dummy/tmp/storage/41/ud/41udni7kfampfsa6dwynr7273y3v +0 -0
- data/spec/dummy/tmp/storage/44/ww/44wwsc9by5wv1u70y9suhuq92bwi +0 -0
- data/spec/dummy/tmp/storage/4b/qe/4bqe6i8rtzlu196bvama05xnumrb +0 -0
- data/spec/dummy/tmp/storage/4n/9p/4n9pgwj5byodmx46ffhpvlydbrmh +0 -0
- data/spec/dummy/tmp/storage/4t/86/4t862kv9wcz0p7wgdvpmtmczdadt +0 -0
- data/spec/dummy/tmp/storage/4t/ke/4tkejzaafw2hopionhrbemj6jrij +0 -0
- data/spec/dummy/tmp/storage/4u/gx/4ugxo9x3cqbwg3d58u13xmtgc6f6 +0 -0
- data/spec/dummy/tmp/storage/57/kn/57kn4d3oyb3uqr0y0hwq4wl4d80i +0 -0
- data/spec/dummy/tmp/storage/5j/ls/5jlsuxajthpnn769oy836amrsavi +0 -0
- data/spec/dummy/tmp/storage/5n/ys/5nyszrcfj6fl2spwxjn1yea42ax0 +0 -0
- data/spec/dummy/tmp/storage/5s/zb/5szbksq6mg3768g9vtk788gc49gw +0 -0
- data/spec/dummy/tmp/storage/5y/zf/5yzft7e8r6cz5pcu78z6jj8dhmbz +0 -0
- data/spec/dummy/tmp/storage/62/jx/62jxz09uvpyv1okycwh7mv6z0gz5 +0 -0
- data/spec/dummy/tmp/storage/66/ed/66edq851b58dvses2okkafxtn827 +0 -0
- data/spec/dummy/tmp/storage/6a/8k/6a8k0jyqprv0z2q3a0p9bwiyy8av +0 -0
- data/spec/dummy/tmp/storage/6d/4e/6d4eiwu6oegnp12mwt27bwhkxe8v +0 -0
- data/spec/dummy/tmp/storage/6g/dc/6gdc40iivivwbln1zs4dqedt5ni7 +0 -0
- data/spec/dummy/tmp/storage/6m/ry/6mrynv03esjb64ohdo4q4xd0wr6t +0 -0
- data/spec/dummy/tmp/storage/6o/7a/6o7ax3ihg25bswxp4d601mqo7tl3 +0 -0
- data/spec/dummy/tmp/storage/6w/uj/6wujip3kahx619bqpcc4myv7tz5n +0 -0
- data/spec/dummy/tmp/storage/6z/86/6z862zpc67sikzl0otbf418t2clj +0 -0
- data/spec/dummy/tmp/storage/70/pb/70pbs8mjus3udsitby6gasexg4qz +0 -0
- data/spec/dummy/tmp/storage/71/rq/71rqssbyrwzhseipt1ojj2aucm2f +0 -0
- data/spec/dummy/tmp/storage/74/nt/74ntaj9azigfadsry359nl8jwbva +0 -0
- data/spec/dummy/tmp/storage/76/qk/76qkxksbv7v7meswa7mcnshr777l +0 -0
- data/spec/dummy/tmp/storage/7g/z0/7gz0olv00p0i3xqdy3f4fa6e73u2 +0 -0
- data/spec/dummy/tmp/storage/82/zv/82zvnds6te3el62i8vxv8rzkc4ms +0 -0
- data/spec/dummy/tmp/storage/83/b1/83b1ejivo3bxawg0kv4f1jufwarp +0 -0
- data/spec/dummy/tmp/storage/84/xr/84xr5dqonkroxjj0nkf3cznat5qt +0 -0
- data/spec/dummy/tmp/storage/8q/oh/8qohqcrf9fh6oc374ewp0lxid5lf +0 -0
- data/spec/dummy/tmp/storage/8v/yv/8vyvd9q13xzmav17gvu5tr1mvlws +0 -0
- data/spec/dummy/tmp/storage/91/35/9135ona6a51xpv669i6wz75kz8pr +0 -0
- data/spec/dummy/tmp/storage/92/hw/92hw9u9j6728qgwpcn7oqphe9tzj +0 -0
- data/spec/dummy/tmp/storage/9a/3q/9a3qd5qc7j6dzzmg16wcpvwoowmp +0 -0
- data/spec/dummy/tmp/storage/9b/2w/9b2w9oc0quy4lsa7y4zvvq8pfnh5 +0 -0
- data/spec/dummy/tmp/storage/9p/cd/9pcdjfvbqndd5dxue0ttlfeew1ht +0 -0
- data/spec/dummy/tmp/storage/al/8s/al8szf81ccm4ckpvxh3bv6vlgp0y +0 -0
- data/spec/dummy/tmp/storage/ao/tx/aotxomcc2m5ojywmr335fc27br55 +0 -0
- data/spec/dummy/tmp/storage/as/3k/as3k29j61efclm810sdnopepmgl2 +0 -0
- data/spec/dummy/tmp/storage/b0/wa/b0wa1zer7y7x8udydx3puofxd3fd +0 -0
- data/spec/dummy/tmp/storage/b8/8l/b88ln7wuq13v4akgwgc0dgac8887 +0 -0
- data/spec/dummy/tmp/storage/bb/iy/bbiyfh0r4f3szj4bmfwp7ptcst6k +0 -0
- data/spec/dummy/tmp/storage/bg/h0/bgh0cuyn7744wfbm8zuob9lugpxu +0 -0
- data/spec/dummy/tmp/storage/bi/6q/bi6qcv9yadwuy9au0q4vojvtqibp +0 -0
- data/spec/dummy/tmp/storage/bm/s6/bms684574m329zo33bmdzw4y05q8 +0 -0
- data/spec/dummy/tmp/storage/bn/8g/bn8gi5i69ysnnedgg57lg6r48hc0 +0 -0
- data/spec/dummy/tmp/storage/bp/0h/bp0hrk5xcf4q8q4b4ypo17ngqy93 +0 -0
- data/spec/dummy/tmp/storage/bs/y9/bsy9t4961ra8hwlq06wjtgrrcflp +0 -0
- data/spec/dummy/tmp/storage/ca/u3/cau32ihv1n1onmqmxf9pbpvwwp42 +0 -0
- data/spec/dummy/tmp/storage/ck/1p/ck1pqdlwjggav333jasfbrtptqs8 +0 -0
- data/spec/dummy/tmp/storage/ck/nb/cknbno5x3oh0nzvrry51ai2c2ce9 +0 -0
- data/spec/dummy/tmp/storage/cp/xd/cpxd4pz21lel4kv0463co0i34dyo +0 -0
- data/spec/dummy/tmp/storage/cq/25/cq25o59ipbdrfn01mtjvi5dwc8v0 +0 -0
- data/spec/dummy/tmp/storage/cq/os/cqosgu11l61u6gdz0c54mr4hasry +0 -0
- data/spec/dummy/tmp/storage/cs/x9/csx9mv26ab1lm82a7itryfq4v6rq +0 -0
- data/spec/dummy/tmp/storage/d5/aa/d5aag1rh6b9stocz1m1pg5c8mnfw +0 -0
- data/spec/dummy/tmp/storage/dm/c1/dmc1zx12pfl41f9br9f1l86953ew +0 -0
- data/spec/dummy/tmp/storage/dp/0f/dp0fx9ji1bqvx1najwjgns6n7fhf +0 -0
- data/spec/dummy/tmp/storage/dq/04/dq04jlw82vqiecdsxyrspe3y8zhd +0 -0
- data/spec/dummy/tmp/storage/dq/p8/dqp8o7eqfob92n81thzhj4mmviwf +0 -0
- data/spec/dummy/tmp/storage/dr/1z/dr1z3xxvya5ywessdrhmk05b2apz +0 -0
- data/spec/dummy/tmp/storage/dr/6z/dr6z0vwwsxqzw0kfkwl598uciyft +0 -0
- data/spec/dummy/tmp/storage/dx/iu/dxiu87gi66esp528s27d805z6b1v +0 -0
- data/spec/dummy/tmp/storage/e2/uo/e2uoyhzlaj5538p6rjs37pbl0z9g +0 -0
- data/spec/dummy/tmp/storage/ef/ih/efihy3gyspz150a8mpmhvj01xr07 +0 -0
- data/spec/dummy/tmp/storage/ej/20/ej20a2w7j929ut3zwo0kk5zyzp96 +0 -0
- data/spec/dummy/tmp/storage/ek/3j/ek3jzmz9919dhom6hbmhglq7e64b +0 -0
- data/spec/dummy/tmp/storage/em/kc/emkc4tc71k65mfcurv6k8z1ylswl +0 -0
- data/spec/dummy/tmp/storage/em/vx/emvx0c15o74mr0nlcvdc7m88j2gi +0 -0
- data/spec/dummy/tmp/storage/ew/n0/ewn0vyho1jbc7i76nat14codqc38 +0 -0
- data/spec/dummy/tmp/storage/f8/hf/f8hf7vk5c1h8s3upvdsgqbrdkokl +0 -0
- data/spec/dummy/tmp/storage/fo/9s/fo9s4w4egoj3qjbwknubsr4m3hca +0 -0
- data/spec/dummy/tmp/storage/fq/m7/fqm72ukjmyc0t6mgh73ehovlhm7i +0 -0
- data/spec/dummy/tmp/storage/ga/7e/ga7eiyyv0llme2i4xby0kdp4a4h8 +0 -0
- data/spec/dummy/tmp/storage/gc/bb/gcbbnsf6rq5xftpvxt4vfo39v2tx +0 -0
- data/spec/dummy/tmp/storage/gc/nn/gcnnb8yfz775d91vymz929zy2b7l +0 -0
- data/spec/dummy/tmp/storage/gv/kd/gvkd1h6f6qqh334ybfn71lwi6xk0 +0 -0
- data/spec/dummy/tmp/storage/gy/t2/gyt2tfjun5ezlgnl6u2ozz2s5wt9 +0 -0
- data/spec/dummy/tmp/storage/h0/i7/h0i7pyghnhpzsss74tk1k9k69yo4 +0 -0
- data/spec/dummy/tmp/storage/h4/86/h486d2xris442m90oylhhdlj1pjg +0 -0
- data/spec/dummy/tmp/storage/h4/vg/h4vgoatz21dhjrztrrbg2hdhkwjb +0 -0
- data/spec/dummy/tmp/storage/h5/13/h513cys269xn45jdhxhfyjlq5b3q +0 -0
- data/spec/dummy/tmp/storage/hb/yf/hbyf2wemy2azh7k1qhn3to9cpbj1 +0 -0
- data/spec/dummy/tmp/storage/hi/9h/hi9ho77symoy2j0ye28fxgnxw3kt +0 -0
- data/spec/dummy/tmp/storage/hl/yy/hlyyu150rt2yos1sa9ed1qw49y26 +0 -0
- data/spec/dummy/tmp/storage/hm/la/hmlataprq9fsh3126h6zmi19u2u1 +0 -0
- data/spec/dummy/tmp/storage/hp/6k/hp6kbroei8cm1chsl2bxhrpbkh1s +0 -0
- data/spec/dummy/tmp/storage/hr/mb/hrmb0w1dnyo6750fj1866f5np7sm +0 -0
- data/spec/dummy/tmp/storage/i9/6r/i96r6te3tutbwgxgl0maf3tgud51 +0 -0
- data/spec/dummy/tmp/storage/ih/xa/ihxalwtv9q6k97ryw0x3di5or5xw +0 -0
- data/spec/dummy/tmp/storage/in/jg/injgf3gi3v8yhpjwy4h8s96k0w8x +0 -0
- data/spec/dummy/tmp/storage/ir/zq/irzqn6i8886usqy6bcnsghmr01kg +0 -0
- data/spec/dummy/tmp/storage/iw/19/iw191t6h61ig4a68n3rk73vjvldc +0 -0
- data/spec/dummy/tmp/storage/j0/jz/j0jz8g89xbvv61ou1cj7dztym5k3 +0 -0
- data/spec/dummy/tmp/storage/j6/ym/j6ymkvvvhcdf7snmc6cardtsy9nd +0 -0
- data/spec/dummy/tmp/storage/j7/6x/j76x0oirv7i4t6p3blseuaknp7pw +0 -0
- data/spec/dummy/tmp/storage/jq/95/jq95rqhv5usgucn2d2mmkhjufapu +0 -0
- data/spec/dummy/tmp/storage/jr/uw/jruwp015m0chh50nxgkklum2ta3u +0 -0
- data/spec/dummy/tmp/storage/jz/ku/jzku30iopsxhh5quij3dov92vpyd +0 -0
- data/spec/dummy/tmp/storage/k0/wi/k0wijnkceisaxvkmc3hbr4croete +0 -0
- data/spec/dummy/tmp/storage/kk/76/kk76rr3nfbi1r4cmw9rcxuorpv4y +0 -0
- data/spec/dummy/tmp/storage/kn/z4/knz4o9yqqnipvbbo2fum9sz2528v +0 -0
- data/spec/dummy/tmp/storage/ky/1y/ky1ys68lmat11bxs2395dqugiyig +0 -0
- data/spec/dummy/tmp/storage/kz/4h/kz4hr1f97wfp44jkt5i3tvheo2hm +0 -0
- data/spec/dummy/tmp/storage/l4/ge/l4gelxdup4epl7lv9x5qyhatk2l6 +0 -0
- data/spec/dummy/tmp/storage/l5/3j/l53jq75i2ywyslq3wl999vl2jmyz +0 -0
- data/spec/dummy/tmp/storage/la/a6/laa6ye8vmuyl7m1gjpkcx19cdpzq +0 -0
- data/spec/dummy/tmp/storage/li/di/lidigrxrlew69ebcfx5ubeb203ck +0 -0
- data/spec/dummy/tmp/storage/ln/0f/ln0fz4opsdycu80q7urfez9ar7kn +0 -0
- data/spec/dummy/tmp/storage/lr/6l/lr6lqlqemfz0aorfbyot2lo9ck4o +0 -0
- data/spec/dummy/tmp/storage/lu/no/lunox74fm54ctc4qbfo2lj9l56sv +0 -0
- data/spec/dummy/tmp/storage/lv/o6/lvo6jno7mebvf0hssv20pgwfyum6 +0 -0
- data/spec/dummy/tmp/storage/m0/tm/m0tml6mrt7hiab73wgr0m9kaizn6 +0 -0
- data/spec/dummy/tmp/storage/mg/z6/mgz6nnkcl4j37w3ev6yolkfxe95o +0 -0
- data/spec/dummy/tmp/storage/mk/4w/mk4w528bsn47ewri0odui9s40f87 +0 -0
- data/spec/dummy/tmp/storage/ms/l9/msl9xauqjm3xnmfpxuiccmznlvnr +0 -0
- data/spec/dummy/tmp/storage/mu/ln/muln4ptnkbcff0s2p54j36goygbx +0 -0
- data/spec/dummy/tmp/storage/na/6r/na6rrohinrnjofsq27u95up5rp8k +0 -0
- data/spec/dummy/tmp/storage/nd/9y/nd9yeusukf9brbkzbm7af1yygidd +0 -0
- data/spec/dummy/tmp/storage/nf/sp/nfspv0s1uw5xo4qtxd8vsvvqy9v7 +0 -0
- data/spec/dummy/tmp/storage/nr/f9/nrf9wi6n0guazfp9gluc36do0dx1 +0 -0
- data/spec/dummy/tmp/storage/nw/le/nwle0hzkvkdl27fqqtm4nmpgzcvp +0 -0
- data/spec/dummy/tmp/storage/nx/64/nx64klyyxu3u3qz5lov4zf23fgco +0 -0
- data/spec/dummy/tmp/storage/nz/kd/nzkd3xlsbohxa2dgfyrz26iqb723 +0 -0
- data/spec/dummy/tmp/storage/o6/xf/o6xfczmxpom0laekvp59gute2p5d +0 -0
- data/spec/dummy/tmp/storage/oc/f8/ocf8zs18lm9fnkpqj6wpshdpyf43 +0 -0
- data/spec/dummy/tmp/storage/oc/xk/ocxkae9a9kkycvpfw71sdhnpqn85 +0 -0
- data/spec/dummy/tmp/storage/oe/bq/oebq593a6bpwkbxpx6segtwyy0jy +0 -0
- data/spec/dummy/tmp/storage/p5/4w/p54wycc6tln36b54yfsz2zk7hcdt +0 -0
- data/spec/dummy/tmp/storage/p9/hd/p9hddsr7pgksgl6vuqgtkp1ad7x2 +0 -0
- data/spec/dummy/tmp/storage/ph/va/phvajdvl6g28vluah7d38rpaj2el +0 -0
- data/spec/dummy/tmp/storage/pi/4i/pi4izeatwyrz6e8zdwvri4f4h4tl +0 -0
- data/spec/dummy/tmp/storage/pu/rl/purlhr67132j7c4k548memz2w2q1 +0 -0
- data/spec/dummy/tmp/storage/pv/bo/pvboa7wami2p1zjkuytzj9epmj14 +0 -0
- data/spec/dummy/tmp/storage/q5/i8/q5i8dg12fdmm5jura53gaw3zj6u4 +0 -0
- data/spec/dummy/tmp/storage/qn/1h/qn1hgmvsrnd8dkn4nvcyvqy3q2sb +0 -0
- data/spec/dummy/tmp/storage/qp/hi/qphia48836lod6l2ao5ca6ocd8ws +0 -0
- data/spec/dummy/tmp/storage/qs/jk/qsjkqiiarr85uobud0qsnnmpraol +0 -0
- data/spec/dummy/tmp/storage/qw/7z/qw7zsf91njf7ga6454nrjpvddjn5 +0 -0
- data/spec/dummy/tmp/storage/r6/6f/r66f8sxtwvlk8c1ava46bgua5hn0 +0 -0
- data/spec/dummy/tmp/storage/ra/6b/ra6b797wpupx6nqkgne3d63j6lh2 +0 -0
- data/spec/dummy/tmp/storage/ra/s0/ras0iwcg9lufnjah5yxyola73jsk +0 -0
- data/spec/dummy/tmp/storage/rd/e4/rde4tqu10zhrceb4uvvorhse4itt +0 -0
- data/spec/dummy/tmp/storage/rh/0h/rh0h80b8er9vp1u8dcocy1u58obf +0 -0
- data/spec/dummy/tmp/storage/ro/wb/rowb68g2iif1e8hsbjdjsmxj94h7 +0 -0
- data/spec/dummy/tmp/storage/s1/22/s122jwsnbcabv9fxp54nhoaaf34u +0 -0
- data/spec/dummy/tmp/storage/s6/on/s6onn1pu2bxcdkeebeu9qaht8i4d +0 -0
- data/spec/dummy/tmp/storage/s8/o0/s8o0enbem94835cqjla6onwncqpz +0 -0
- data/spec/dummy/tmp/storage/s9/lw/s9lwslyf5co34pvbt3n9ay06ui2w +0 -0
- data/spec/dummy/tmp/storage/sb/bo/sbboin8iacxsa7ywl1xp401f7tmj +0 -0
- data/spec/dummy/tmp/storage/sd/he/sdhe8pgaioyf7kdmdok21dy8enr3 +0 -0
- data/spec/dummy/tmp/storage/si/24/si24loctkg3h900v6vaoxwnruih7 +0 -0
- data/spec/dummy/tmp/storage/st/hv/sthv2tx2r8zv6tyn9yxi5am0pgzh +0 -0
- data/spec/dummy/tmp/storage/su/ng/sungqllfkjesc0p9c8hz3y2ior41 +0 -0
- data/spec/dummy/tmp/storage/sy/wq/sywqphj8vgv0imntn38s286yjjc3 +0 -0
- data/spec/dummy/tmp/storage/ta/s3/tas35nm4h81nhaecpeybk8kxzt62 +0 -0
- data/spec/dummy/tmp/storage/tc/gu/tcgurel05x9fk9ksm4hxwfla3hg3 +0 -0
- data/spec/dummy/tmp/storage/tk/rt/tkrtpgn5p68rqy679q15ab3j7twz +0 -0
- data/spec/dummy/tmp/storage/tm/ce/tmce54998rdnz191k02fzowpebvw +0 -0
- data/spec/dummy/tmp/storage/tt/pu/ttpumlt7wi54pohcc7ktsl5le777 +0 -0
- data/spec/dummy/tmp/storage/u1/vf/u1vfyawqqy7wpkthgardxs358car +0 -0
- data/spec/dummy/tmp/storage/u2/xa/u2xaxpjz4fdxtxxinaxq2r7biovv +0 -0
- data/spec/dummy/tmp/storage/uf/67/uf67aznvgtom02vj8q4jl60hycfm +0 -0
- data/spec/dummy/tmp/storage/ui/xi/uixi7xtks88zuqr4gwi6cjbk4m47 +0 -0
- data/spec/dummy/tmp/storage/uq/jk/uqjkltli1s6vz51g6yu551ze48c1 +0 -0
- data/spec/dummy/tmp/storage/ux/te/uxtezp2rqztn4cernmn7477gukxe +0 -0
- data/spec/dummy/tmp/storage/v4/yi/v4yieu5kcx0jz3ephiptzr46djev +0 -0
- data/spec/dummy/tmp/storage/va/sc/vascc4h0c7dv7uwwcn2wdvx6qyhy +0 -0
- data/spec/dummy/tmp/storage/vp/ub/vpub3n9dk3ts14cvq9tvkez7crqq +0 -0
- data/spec/dummy/tmp/storage/w2/3f/w23f3igzkn7bddqxry5x4wsu2ths +0 -0
- data/spec/dummy/tmp/storage/w4/1j/w41judbhn1j3quwhs36myqwnypkz +0 -0
- data/spec/dummy/tmp/storage/w4/d3/w4d3qfnguynfuw4oxo5hek8q5w66 +0 -0
- data/spec/dummy/tmp/storage/w9/na/w9na14949rr42w928n9srevxecbl +0 -0
- data/spec/dummy/tmp/storage/wo/81/wo813rsnwvoa55h0vq0fr79iajuw +0 -0
- data/spec/dummy/tmp/storage/wp/zs/wpzs5finp3t36za2bykcoxueu5b6 +0 -0
- data/spec/dummy/tmp/storage/wv/9t/wv9t3gxm6dqah7kdq74pimjdb156 +0 -0
- data/spec/dummy/tmp/storage/ww/40/ww40d8rykhlpxwfh0ggfs7mrh0jl +0 -0
- data/spec/dummy/tmp/storage/wy/14/wy14megn3o5zqplv9xg6u32uwkr6 +0 -0
- data/spec/dummy/tmp/storage/xd/4h/xd4h96rdmw5t9pujgz831cnfgj8o +0 -0
- data/spec/dummy/tmp/storage/xi/en/xiensi0706n8m0x5lxp0fbwg8ipk +0 -0
- data/spec/dummy/tmp/storage/xj/yy/xjyygdd3znvvpt9ufz1vv4lfsx3w +0 -0
- data/spec/dummy/tmp/storage/xs/x1/xsx109k9pb83qze3raurxo22dnms +0 -0
- data/spec/dummy/tmp/storage/xv/gf/xvgf6x0othqxlxcbgwz4sg7th3p9 +0 -0
- data/spec/dummy/tmp/storage/y5/3g/y53gv7ysx4j1y0k71pszym8sdu6b +0 -0
- data/spec/dummy/tmp/storage/ya/yf/yayfpxlrbtz0578nl9tlourrwe27 +0 -0
- data/spec/dummy/tmp/storage/yd/x8/ydx8jm52rnl3b7mpvmmxlilenllw +0 -0
- data/spec/dummy/tmp/storage/ye/bu/yebu3imdihqdatzktkubhkto82xo +0 -0
- data/spec/dummy/tmp/storage/yf/49/yf49a4ydheqf3cqs0u49sanbl4ms +0 -0
- data/spec/dummy/tmp/storage/yh/q1/yhq1muao2dpuykmj12bxhd0x4ntk +0 -0
- data/spec/dummy/tmp/storage/ym/5n/ym5ndg2m03vfnoeryvb9tex8xj72 +0 -0
- data/spec/dummy/tmp/storage/yx/jp/yxjpumjyo1jysjpg20qaxgsqg4fw +0 -0
- data/spec/dummy/tmp/storage/z1/gr/z1grp34d5vw7mi4g8vw8yfu91ny2 +0 -0
- data/spec/dummy/tmp/storage/z5/qs/z5qs5fq00igr3xv5izgcyhhsdw7y +0 -0
- data/spec/dummy/tmp/storage/z5/sg/z5sgd1au9gcfkqb3kq82f3yry6a6 +0 -0
- data/spec/dummy/tmp/storage/z7/8n/z78nuzozxx53c7cpp3e4kt3nghaa +0 -0
- data/spec/dummy/tmp/storage/zk/3v/zk3vlz1al2rba9wlkzoa6p8wpli0 +0 -0
- data/spec/dummy/tmp/storage/zk/xs/zkxsr1zywhaydz0cep4eh8mmos46 +0 -0
- data/spec/dummy/tmp/storage/zx/ur/zxuraz59df480azmknqbfeb37ktm +0 -0
- data/spec/examples.txt +126 -0
- data/spec/factories/snf_core/addresses.rb +10 -0
- data/spec/factories/snf_core/business_documents.rb +18 -0
- data/spec/factories/snf_core/businesses.rb +10 -0
- data/spec/factories/snf_core/categories.rb +7 -0
- data/spec/factories/snf_core/customer_groups.rb +9 -0
- data/spec/factories/snf_core/delivery_orders.rb +36 -0
- data/spec/factories/snf_core/groups.rb +6 -0
- data/spec/factories/snf_core/order_items.rb +9 -0
- data/spec/factories/snf_core/orders.rb +33 -0
- data/spec/factories/snf_core/products.rb +9 -0
- data/spec/factories/snf_core/roles.rb +5 -0
- data/spec/factories/snf_core/store_inventories.rb +8 -0
- data/spec/factories/snf_core/stores.rb +9 -0
- data/spec/factories/snf_core/user_roles.rb +6 -0
- data/spec/factories/snf_core/users.rb +12 -0
- data/spec/factories/snf_core/wallets.rb +7 -0
- data/spec/mailers/previews/snf_core/auth_mailer_preview.rb +6 -0
- data/spec/mailers/snf_core/auth_mailer_spec.rb +7 -0
- data/spec/models/snf_core/address_spec.rb +15 -0
- data/spec/models/snf_core/business_document_spec.rb +20 -0
- data/spec/models/snf_core/business_spec.rb +14 -0
- data/spec/models/snf_core/category_spec.rb +12 -0
- data/spec/models/snf_core/customer_group_spec.rb +11 -0
- data/spec/models/snf_core/delivery_order_spec.rb +70 -0
- data/spec/models/snf_core/group_spec.rb +11 -0
- data/spec/models/snf_core/order_item_spec.rb +64 -0
- data/spec/models/snf_core/order_spec.rb +81 -0
- data/spec/models/snf_core/product_spec.rb +17 -0
- data/spec/models/snf_core/role_spec.rb +12 -0
- data/spec/models/snf_core/store_inventory_spec.rb +24 -0
- data/spec/models/snf_core/store_spec.rb +13 -0
- data/spec/models/snf_core/user_role_spec.rb +11 -0
- data/spec/models/snf_core/user_spec.rb +22 -0
- data/spec/models/snf_core/wallet_spec.rb +28 -0
- data/spec/rails_helper.rb +46 -0
- data/spec/requests/snf_core/auth_spec.rb +139 -0
- data/spec/sample_spec.rb +5 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/models/shared_examples.rb +49 -0
- data/spec/support/requests/shared_requests.rb +130 -0
- metadata +320 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ba7ee61a617e2f1740360b891c9445fc4085c217ef2a4b7b6ad516ff963439e
|
4
|
+
data.tar.gz: 3d9d5f1fb249faa10260f1cf212f4e298b4c592dfd82a90cc208d2f0004df4f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcc130397675fd339b51ebdf9c1456b1dd8b53747e143738ddd718885906a78199584fe0248370ad4dd61f5578a1f289794090fe5ec55dc6ff463ebf55508db8
|
7
|
+
data.tar.gz: ad9ca802d840ab9fc10f21770f3216e602b83987cc6334589b969e572c20a67bb98ea92d4ec0de399a7a2bfef16d20e686ec263f647f7e9ad58728bd9fe4f7b2
|
data/MIT-LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/Rakefile
CHANGED
File without changes
|
File without changes
|
File without changes
|
@@ -1,4 +1,37 @@
|
|
1
1
|
module SnfCore
|
2
2
|
class ApplicationController < ActionController::API
|
3
|
+
private
|
4
|
+
|
5
|
+
def is_authenticated
|
6
|
+
render json: { error: "Not authenticated" }, status: :unauthorized unless current_user
|
7
|
+
end
|
8
|
+
|
9
|
+
def is_allowed
|
10
|
+
user_role = UserRole.find_by(user: current_user)
|
11
|
+
role = Role.find(user_role.role_id)
|
12
|
+
render json: { error: "Not authorized" }, status: :ok unless role.name == "registrar" || role.name == "dean"
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_user
|
16
|
+
return @current_user if defined?(@current_user)
|
17
|
+
|
18
|
+
return unless auth_token
|
19
|
+
|
20
|
+
begin
|
21
|
+
payload = TokenService.new.decode(auth_token)
|
22
|
+
@current_user = User.find_by(id: payload["user"]["id"])
|
23
|
+
rescue JWT::DecodeError => e
|
24
|
+
Rails.logger.warn "Token decode error: #{e.message}"
|
25
|
+
nil
|
26
|
+
rescue ActiveRecord::RecordNotFound => e
|
27
|
+
Rails.logger.warn "User not found: #{e.message}"
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth_token
|
33
|
+
auth_header = request.headers["Authorization"]
|
34
|
+
auth_header&.split(" ")&.last
|
35
|
+
end
|
3
36
|
end
|
4
37
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module SnfCore
|
2
|
+
class AuthController < ApplicationController
|
3
|
+
before_action :token_service
|
4
|
+
|
5
|
+
def login
|
6
|
+
user = User.find_by(phone_number: auth_params[:phone_number])
|
7
|
+
return render json: { success: false, error: "User doesn't exist" }, status: :unauthorized unless user
|
8
|
+
return render json: { success: false, warn: true, error: "Password has not been reset please reset your password to continue!" }, status: :unauthorized unless user.password_changed
|
9
|
+
return render json: { success: false, error: "Invalid email or password" }, status: :unauthorized unless user.authenticate(auth_params[:password])
|
10
|
+
user_role = UserRole.find_by(user: user)
|
11
|
+
return render json: { success: false, error: "No role was assigned to your user" }, status: :unauthorized unless user_role
|
12
|
+
|
13
|
+
role = Role.find(user_role.role_id)
|
14
|
+
token = @token_service.encode({ user: user.as_json.except("password_digest", "created_at", "updated_at"), role: role.name })
|
15
|
+
render json: { success: true, token: token }
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_password_request
|
19
|
+
user = User.find_by(phone_number: auth_params[:phone_number])
|
20
|
+
return render json: { success: false, error: "User doesn't exist" }, status: :unauthorized unless user
|
21
|
+
user.reset_password_token = SecureRandom.hex
|
22
|
+
user.save!
|
23
|
+
AuthMailer.with(
|
24
|
+
user: user,
|
25
|
+
reset_url: params[:reset_url] || "http://localhost:3000/reset-password"
|
26
|
+
).reset_password.deliver_now
|
27
|
+
render json: { success: true, message: "Reset password token sent to your email" }
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset_password
|
31
|
+
user = User.find_by(reset_password_token: auth_params[:reset_password_token])
|
32
|
+
return render json: { success: false, error: "Token has expired please try again!" }, status: :unauthorized unless user
|
33
|
+
if user.reset_password_token == auth_params[:reset_password_token]
|
34
|
+
return render json: { success: false, error: "You can't use the same password as your current password" }, status: :unprocessable_entity if BCrypt::Password.new(user.password_digest) == auth_params[:password]
|
35
|
+
user.password = auth_params[:password]
|
36
|
+
user.reset_password_token = nil
|
37
|
+
user.password_changed = true
|
38
|
+
user.save!
|
39
|
+
render json: { success: true, message: "Password reset successfully" }
|
40
|
+
else
|
41
|
+
user.reset_password_token = nil
|
42
|
+
user.save!
|
43
|
+
render json: { success: false, error: "Reset password token doesn't match try again" }, status: :unprocessable_entity
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def change_password
|
48
|
+
user = current_user
|
49
|
+
if user && user.authenticate(auth_params[:password])
|
50
|
+
return render json: { success: false, error: "Can't use the same password as your current password" }, status: :unprocessable_entity if BCrypt::Password.new(user.password_digest) == auth_params[:new_password]
|
51
|
+
user.password = auth_params[:new_password]
|
52
|
+
user.password_changed = true
|
53
|
+
user.save!
|
54
|
+
render json: { success: true, message: "Password changed successfully" }
|
55
|
+
else
|
56
|
+
render json: { success: false, error: "Invalid password" }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def token_service
|
63
|
+
@token_service ||= SnfCore::TokenService.new
|
64
|
+
end
|
65
|
+
|
66
|
+
def auth_params
|
67
|
+
params.require(:auth).permit(:phone_number, :password, :password_confirmation, :reset_password_token, :new_password)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SnfCore
|
2
|
+
class AuthMailer < ApplicationMailer
|
3
|
+
def reset_password
|
4
|
+
@user = params[:user]
|
5
|
+
@reset_url = "#{params[:reset_url] || 'http://localhost:3000/reset-password'}/#{@user.reset_password_token}"
|
6
|
+
|
7
|
+
mail(
|
8
|
+
to: @user.email,
|
9
|
+
subject: "Reset Your Password"
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,15 +1,15 @@
|
|
1
|
-
module SnfCore
|
2
|
-
class BusinessDocument < ApplicationRecord
|
3
|
-
belongs_to :business
|
4
|
-
belongs_to :verified_by, class_name: "SnfCore::User", optional: true
|
5
|
-
|
6
|
-
enum :document_type, {
|
7
|
-
|
8
|
-
|
9
|
-
},
|
10
|
-
|
11
|
-
has_one_attached :document
|
12
|
-
|
13
|
-
validates :document_type, :uploaded_at, :document, presence: true
|
14
|
-
end
|
15
|
-
end
|
1
|
+
module SnfCore
|
2
|
+
class BusinessDocument < ApplicationRecord
|
3
|
+
belongs_to :business
|
4
|
+
belongs_to :verified_by, class_name: "SnfCore::User", optional: true
|
5
|
+
|
6
|
+
enum :document_type, {
|
7
|
+
business_license_doc: 0,
|
8
|
+
representative_id_doc: 1
|
9
|
+
}, prefix: :document
|
10
|
+
|
11
|
+
has_one_attached :document
|
12
|
+
|
13
|
+
validates :document_type, :uploaded_at, :document, presence: true
|
14
|
+
end
|
15
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SnfCore
|
2
|
+
class DeliveryOrder < ApplicationRecord
|
3
|
+
belongs_to :order
|
4
|
+
|
5
|
+
validates :delivery_address, :contact_phone, :delivery_notes,
|
6
|
+
:estimated_delivery_time, :status, presence: true
|
7
|
+
|
8
|
+
enum :status, {
|
9
|
+
pending: 0,
|
10
|
+
assigned: 1,
|
11
|
+
picked_up: 2,
|
12
|
+
in_transit: 3,
|
13
|
+
delivered: 4,
|
14
|
+
failed: 5,
|
15
|
+
cancelled: 6
|
16
|
+
}
|
17
|
+
|
18
|
+
def assign!
|
19
|
+
update!(status: :assigned) if pending?
|
20
|
+
end
|
21
|
+
|
22
|
+
def pick_up!
|
23
|
+
update!(status: :picked_up) if assigned?
|
24
|
+
end
|
25
|
+
|
26
|
+
def start_transit!
|
27
|
+
update!(status: :in_transit) if picked_up?
|
28
|
+
end
|
29
|
+
|
30
|
+
def mark_delivered!
|
31
|
+
update!(status: :delivered, actual_delivery_time: Time.current) if in_transit?
|
32
|
+
end
|
33
|
+
|
34
|
+
def mark_failed!
|
35
|
+
update!(status: :failed) unless delivered?
|
36
|
+
end
|
37
|
+
|
38
|
+
def cancel!
|
39
|
+
update!(status: :cancelled) unless delivered? || failed?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
File without changes
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module SnfCore
|
2
|
+
class Order < ApplicationRecord
|
3
|
+
belongs_to :user
|
4
|
+
belongs_to :store
|
5
|
+
has_many :order_items, dependent: :destroy
|
6
|
+
has_many :store_inventories, through: :order_items
|
7
|
+
|
8
|
+
enum :status, {
|
9
|
+
pending: 0,
|
10
|
+
confirmed: 1,
|
11
|
+
processing: 2,
|
12
|
+
shipped: 3,
|
13
|
+
delivered: 4,
|
14
|
+
cancelled: 5
|
15
|
+
}
|
16
|
+
|
17
|
+
validates :status, presence: true
|
18
|
+
validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
19
|
+
|
20
|
+
before_validation :calculate_total_amount
|
21
|
+
before_create :set_initial_status
|
22
|
+
after_create :process_order
|
23
|
+
|
24
|
+
def confirm!
|
25
|
+
update!(status: :confirmed) if pending?
|
26
|
+
end
|
27
|
+
|
28
|
+
def process!
|
29
|
+
update!(status: :processing) if confirmed?
|
30
|
+
end
|
31
|
+
|
32
|
+
def ship!
|
33
|
+
update!(status: :shipped) if processing?
|
34
|
+
end
|
35
|
+
|
36
|
+
def deliver!
|
37
|
+
update!(status: :delivered) if shipped?
|
38
|
+
end
|
39
|
+
|
40
|
+
def cancel!
|
41
|
+
update!(status: :cancelled) unless delivered?
|
42
|
+
end
|
43
|
+
|
44
|
+
def total_amount
|
45
|
+
order_items.reload.sum { |item| item.quantity * item.unit_price }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def calculate_total_amount
|
51
|
+
self[:total_amount] = total_amount
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_initial_status
|
55
|
+
self.status ||= :pending
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_order
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def calculate_total_amount
|
65
|
+
self.total_amount = order_items.sum(&:subtotal) || 0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SnfCore
|
2
|
+
class OrderItem < ApplicationRecord
|
3
|
+
belongs_to :order
|
4
|
+
belongs_to :store_inventory
|
5
|
+
|
6
|
+
validates :quantity, presence: true, numericality: { greater_than: 0 }
|
7
|
+
validates :unit_price, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
8
|
+
validates :subtotal, presence: true, numericality: true
|
9
|
+
|
10
|
+
before_validation :calculate_subtotal
|
11
|
+
after_save :update_order_total
|
12
|
+
after_destroy :update_order_total
|
13
|
+
|
14
|
+
def subtotal
|
15
|
+
return 0 unless quantity.present? && unit_price.present?
|
16
|
+
quantity.to_f * unit_price.to_f
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def calculate_subtotal
|
22
|
+
return unless quantity.present? && unit_price.present?
|
23
|
+
self.subtotal = quantity.to_f * unit_price.to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
def update_order_total
|
27
|
+
order.reload.valid? if order.present?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
data/app/models/snf_core/user.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
module SnfCore
|
2
|
-
class User < ApplicationRecord
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
after_create :create_default_wallet
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def create_default_wallet
|
15
|
-
create_wallet(balance: 0.0, is_active: true)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
1
|
+
module SnfCore
|
2
|
+
class User < ApplicationRecord
|
3
|
+
has_secure_password
|
4
|
+
|
5
|
+
has_one :wallet, dependent: :destroy
|
6
|
+
|
7
|
+
validates :first_name, :middle_name, :last_name, :phone_number, presence: true
|
8
|
+
validates :phone_number, :email, uniqueness: true
|
9
|
+
|
10
|
+
after_create :create_default_wallet
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def create_default_wallet
|
15
|
+
create_wallet(balance: 0.0, is_active: true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "jwt"
|
2
|
+
|
3
|
+
module SnfCore
|
4
|
+
class TokenService
|
5
|
+
def encode(payload)
|
6
|
+
JWT.encode(payload, ENV["SECRET_KEY_BASE"] || "secret_key_base")
|
7
|
+
end
|
8
|
+
|
9
|
+
def decode(token)
|
10
|
+
body = JWT.decode(token, ENV["SECRET_KEY_BASE"] || "secret_key_base")[0]
|
11
|
+
HashWithIndifferentAccess.new body
|
12
|
+
rescue
|
13
|
+
raise StandardError.new("Invalid token")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
5
|
+
<style>
|
6
|
+
body {
|
7
|
+
font-family: Arial, sans-serif;
|
8
|
+
line-height: 1.6;
|
9
|
+
color: #333333;
|
10
|
+
margin: 0;
|
11
|
+
padding: 0;
|
12
|
+
background-color: #f4f4f4;
|
13
|
+
}
|
14
|
+
.container {
|
15
|
+
max-width: 600px;
|
16
|
+
margin: 0 auto;
|
17
|
+
padding: 20px;
|
18
|
+
background-color: #ffffff;
|
19
|
+
}
|
20
|
+
.header {
|
21
|
+
background-color: #4A1E1B;
|
22
|
+
color: #ffffff;
|
23
|
+
padding: 20px;
|
24
|
+
text-align: center;
|
25
|
+
}
|
26
|
+
.content {
|
27
|
+
padding: 20px;
|
28
|
+
}
|
29
|
+
.footer {
|
30
|
+
text-align: center;
|
31
|
+
padding: 20px;
|
32
|
+
font-size: 12px;
|
33
|
+
color: #666666;
|
34
|
+
border-top: 1px solid #eeeeee;
|
35
|
+
}
|
36
|
+
.button {
|
37
|
+
display: inline-block;
|
38
|
+
padding: 10px 20px;
|
39
|
+
background-color: #4A1E1B;
|
40
|
+
color: #ffffff;
|
41
|
+
text-decoration: none;
|
42
|
+
border-radius: 4px;
|
43
|
+
margin: 10px 0;
|
44
|
+
}
|
45
|
+
.button:hover {
|
46
|
+
background-color: #623431;
|
47
|
+
}
|
48
|
+
</style>
|
49
|
+
</head>
|
50
|
+
|
51
|
+
<body>
|
52
|
+
<div class="container">
|
53
|
+
<div class="header">
|
54
|
+
<h1>BUNNA</h1>
|
55
|
+
</div>
|
56
|
+
<div class="content">
|
57
|
+
<%= yield %>
|
58
|
+
</div>
|
59
|
+
<div class="footer">
|
60
|
+
© <%= Time.current.year %> BUNNA. All rights reserved.
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
</body>
|
64
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="content">
|
2
|
+
<h2>Reset Your Password</h2>
|
3
|
+
<p>Hello <%= @user.first_name %>,</p>
|
4
|
+
<p>You have requested to reset your password. Click the link below to set a new password:</p>
|
5
|
+
|
6
|
+
<p><a href="<%= @reset_url %>">Reset Password</a></p>
|
7
|
+
|
8
|
+
<p>If you didn't request this, please ignore this email.</p>
|
9
|
+
<p>This link will expire in 24 hours.</p>
|
10
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
class CreateSnfCoreUsers < ActiveRecord::Migration[8.0]
|
2
|
-
def change
|
3
|
-
create_table :snf_core_users do |t|
|
4
|
-
t.string :first_name, null: false
|
5
|
-
t.string :middle_name, null: false
|
6
|
-
t.string :last_name, null: false
|
7
|
-
t.string :email
|
8
|
-
t.string :phone_number, null: false
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
1
|
+
class CreateSnfCoreUsers < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :snf_core_users do |t|
|
4
|
+
t.string :first_name, null: false
|
5
|
+
t.string :middle_name, null: false
|
6
|
+
t.string :last_name, null: false
|
7
|
+
t.string :email
|
8
|
+
t.string :phone_number, null: false
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSnfCoreOrders < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :snf_core_orders do |t|
|
4
|
+
t.references :user, null: false, foreign_key: { to_table: :snf_core_users }
|
5
|
+
t.references :store, null: false, foreign_key: { to_table: :snf_core_stores }
|
6
|
+
t.integer :status, null: false, default: 1
|
7
|
+
t.decimal :total_amount, null: false, default: 0
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateSnfCoreOrderItems < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :snf_core_order_items do |t|
|
4
|
+
t.references :order, null: false, foreign_key: { to_table: :snf_core_orders }
|
5
|
+
t.references :store_inventory, null: false, foreign_key: { to_table: :snf_core_store_inventories }
|
6
|
+
t.integer :quantity, null: false
|
7
|
+
t.decimal :unit_price, null: false
|
8
|
+
t.decimal :subtotal, null: false
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateSnfCoreDeliveryOrders < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :snf_core_delivery_orders do |t|
|
4
|
+
t.references :order, null: false, foreign_key: { to_table: :snf_core_orders }
|
5
|
+
t.string :delivery_address, null: false
|
6
|
+
t.string :contact_phone, null: false
|
7
|
+
t.text :delivery_notes, null: false
|
8
|
+
t.datetime :estimated_delivery_time, null: false
|
9
|
+
t.datetime :actual_delivery_time
|
10
|
+
t.integer :status, null: false
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateSnfCoreUserRoles < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :snf_core_user_roles do |t|
|
4
|
+
t.references :user, null: false, foreign_key: {to_table: :snf_core_users}
|
5
|
+
t.references :role, null: false, foreign_key: {to_table: :snf_core_roles}
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class AddPasswordFieldsToSnfCoreUsers < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
add_column :snf_core_users, :password_digest, :string, null: false
|
4
|
+
add_column :snf_core_users, :password_changed, :boolean, default: false
|
5
|
+
add_column :snf_core_users, :reset_password_token, :string, null: true
|
6
|
+
end
|
7
|
+
end
|
data/lib/snf_core/engine.rb
CHANGED
File without changes
|
data/lib/snf_core/version.rb
CHANGED
data/lib/snf_core.rb
CHANGED
File without changes
|
File without changes
|