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.
Files changed (356) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +0 -0
  3. data/README.md +0 -0
  4. data/Rakefile +0 -0
  5. data/app/controllers/concerns/common.rb +0 -0
  6. data/app/controllers/concerns/pagination.rb +0 -0
  7. data/app/controllers/snf_core/application_controller.rb +33 -0
  8. data/app/controllers/snf_core/auth_controller.rb +70 -0
  9. data/app/jobs/snf_core/application_job.rb +0 -0
  10. data/app/mailers/snf_core/application_mailer.rb +0 -0
  11. data/app/mailers/snf_core/auth_mailer.rb +13 -0
  12. data/app/models/snf_core/address.rb +0 -0
  13. data/app/models/snf_core/application_record.rb +0 -0
  14. data/app/models/snf_core/business.rb +0 -0
  15. data/app/models/snf_core/business_document.rb +15 -15
  16. data/app/models/snf_core/category.rb +0 -0
  17. data/app/models/snf_core/customer_group.rb +0 -0
  18. data/app/models/snf_core/delivery_order.rb +42 -0
  19. data/app/models/snf_core/group.rb +0 -0
  20. data/app/models/snf_core/order.rb +68 -0
  21. data/app/models/snf_core/order_item.rb +30 -0
  22. data/app/models/snf_core/product.rb +0 -0
  23. data/app/models/snf_core/role.rb +8 -0
  24. data/app/models/snf_core/store.rb +0 -0
  25. data/app/models/snf_core/store_inventory.rb +0 -0
  26. data/app/models/snf_core/user.rb +18 -18
  27. data/app/models/snf_core/user_role.rb +6 -0
  28. data/app/models/snf_core/wallet.rb +0 -0
  29. data/app/services/snf_core/token_service.rb +16 -0
  30. data/app/views/layouts/snf_core/mailer.html.erb +64 -0
  31. data/app/views/layouts/snf_core/mailer.text.erb +1 -0
  32. data/app/views/snf_core/auth_mailer/reset_password.html.erb +10 -0
  33. data/config/routes.rb +5 -0
  34. data/db/migrate/20250226042622_create_snf_core_users.rb +13 -14
  35. data/db/migrate/20250226064444_create_snf_core_categories.rb +0 -0
  36. data/db/migrate/20250226080323_create_snf_core_businesses.rb +0 -0
  37. data/db/migrate/20250226102931_create_snf_core_business_documents.rb +0 -0
  38. data/db/migrate/20250226110217_create_snf_core_addresses.rb +0 -0
  39. data/db/migrate/20250226115215_create_snf_core_stores.rb +0 -0
  40. data/db/migrate/20250226181007_create_snf_core_products.rb +0 -0
  41. data/db/migrate/20250226190000_create_snf_core_store_inventories.rb +0 -0
  42. data/db/migrate/20250226192104_create_snf_core_groups.rb +0 -0
  43. data/db/migrate/20250226193938_create_snf_core_customer_groups.rb +0 -0
  44. data/db/migrate/20250227075048_create_snf_core_wallets.rb +0 -0
  45. data/db/migrate/20250227102833_modify_store_inventories.rb +0 -0
  46. data/db/migrate/20250305165926_create_snf_core_orders.rb +12 -0
  47. data/db/migrate/20250305170248_create_snf_core_order_items.rb +13 -0
  48. data/db/migrate/20250305201008_create_snf_core_delivery_orders.rb +15 -0
  49. data/db/migrate/20250305232529_create_snf_core_roles.rb +9 -0
  50. data/db/migrate/20250305232530_create_snf_core_user_roles.rb +10 -0
  51. data/db/migrate/20250306074713_add_password_fields_to_snf_core_users.rb +7 -0
  52. data/lib/snf_core/engine.rb +0 -0
  53. data/lib/snf_core/version.rb +1 -1
  54. data/lib/snf_core.rb +0 -0
  55. data/lib/tasks/snf_core_tasks.rake +0 -0
  56. data/spec/dummy/Rakefile +6 -0
  57. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  58. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  59. data/spec/dummy/app/jobs/application_job.rb +7 -0
  60. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  61. data/spec/dummy/app/models/application_record.rb +3 -0
  62. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  63. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  64. data/spec/dummy/bin/dev +2 -0
  65. data/spec/dummy/bin/rails +4 -0
  66. data/spec/dummy/bin/rake +4 -0
  67. data/spec/dummy/bin/setup +34 -0
  68. data/spec/dummy/config/application.rb +43 -0
  69. data/spec/dummy/config/boot.rb +5 -0
  70. data/spec/dummy/config/cable.yml +10 -0
  71. data/spec/dummy/config/database.yml +20 -0
  72. data/spec/dummy/config/environment.rb +5 -0
  73. data/spec/dummy/config/environments/development.rb +86 -0
  74. data/spec/dummy/config/environments/production.rb +86 -0
  75. data/spec/dummy/config/environments/test.rb +53 -0
  76. data/spec/dummy/config/initializers/cors.rb +16 -0
  77. data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
  78. data/spec/dummy/config/initializers/inflections.rb +16 -0
  79. data/spec/dummy/config/locales/en.yml +31 -0
  80. data/spec/dummy/config/puma.rb +38 -0
  81. data/spec/dummy/config/routes.rb +3 -0
  82. data/spec/dummy/config/storage.yml +38 -0
  83. data/spec/dummy/config.ru +6 -0
  84. data/spec/dummy/db/migrate/20250226123213_create_active_storage_tables.active_storage.rb +57 -0
  85. data/spec/dummy/db/schema.rb +242 -0
  86. data/spec/dummy/log/development.log +3026 -0
  87. data/spec/dummy/log/test.log +133760 -0
  88. data/spec/dummy/spec/fixtures/files/sample.pdf +0 -0
  89. data/spec/dummy/tmp/letter_opener/1741263210_267596_73bfefe/rich.html +142 -0
  90. data/spec/dummy/tmp/letter_opener/1741263645_7876108_3edd95c/rich.html +132 -0
  91. data/spec/dummy/tmp/letter_opener/1741263812_8855171_0bf8e2b/rich.html +132 -0
  92. data/spec/dummy/tmp/local_secret.txt +1 -0
  93. data/spec/dummy/tmp/pids/server.pid +1 -0
  94. data/spec/dummy/tmp/restart.txt +0 -0
  95. data/spec/dummy/tmp/storage/05/zb/05zbh3dr63t1ktnsxkwk2ugbglbu +0 -0
  96. data/spec/dummy/tmp/storage/0u/er/0uerkm5uy46p3lvg18c7ond00lih +0 -0
  97. data/spec/dummy/tmp/storage/13/1y/131yod70wqijazn3ix829yvuuvge +0 -0
  98. data/spec/dummy/tmp/storage/16/na/16na9nc1z98jt6fyn3axj3bhudes +0 -0
  99. data/spec/dummy/tmp/storage/17/wb/17wbd1yhh3pyg3j1sko570vsjnpq +0 -0
  100. data/spec/dummy/tmp/storage/1e/s9/1es9g1a309tf4bs04mr0i70usjz1 +0 -0
  101. data/spec/dummy/tmp/storage/1j/tj/1jtjythzzcpbajktrsn08af3x66m +0 -0
  102. data/spec/dummy/tmp/storage/1t/oy/1toyz0i6f9u5xexr4cpwttr04ood +0 -0
  103. data/spec/dummy/tmp/storage/1v/u3/1vu3btk2ukaxgp84qfmk5izonqmi +0 -0
  104. data/spec/dummy/tmp/storage/1x/i3/1xi33eqr5ipoaz0upakb8yy7qc4o +0 -0
  105. data/spec/dummy/tmp/storage/22/xs/22xscg5bqqtdykdaxrbr388lxkmf +0 -0
  106. data/spec/dummy/tmp/storage/24/69/2469t9kpepg4fd8ki960h025li0b +0 -0
  107. data/spec/dummy/tmp/storage/2a/0u/2a0uyihfk1wn5c1fuz09unocwy2m +0 -0
  108. data/spec/dummy/tmp/storage/2e/f9/2ef9j9go5h1v9ain8zq8m9zpjsf3 +0 -0
  109. data/spec/dummy/tmp/storage/2i/e3/2ie3ve4rajer9sx5zf6r45b3r9ar +0 -0
  110. data/spec/dummy/tmp/storage/2n/56/2n569vuf39piqdtbtbxsztn3r6kl +0 -0
  111. data/spec/dummy/tmp/storage/2o/te/2ote6co29576cnoptsem3lhupuxy +0 -0
  112. data/spec/dummy/tmp/storage/32/ur/32ur9eb5d0h01m2oe9kc5avpm31u +0 -0
  113. data/spec/dummy/tmp/storage/35/ov/35ovg8m7ij4fjqy3v4bh28e5hld2 +0 -0
  114. data/spec/dummy/tmp/storage/37/x2/37x2up33wqtrua85c089e6ltr49p +0 -0
  115. data/spec/dummy/tmp/storage/3i/8d/3i8dbcb1dk9ri0kumm3th8wo61gc +0 -0
  116. data/spec/dummy/tmp/storage/3u/jh/3ujhd5drl4t2nfbqw7ij2jzijxn1 +0 -0
  117. data/spec/dummy/tmp/storage/41/ud/41udni7kfampfsa6dwynr7273y3v +0 -0
  118. data/spec/dummy/tmp/storage/44/ww/44wwsc9by5wv1u70y9suhuq92bwi +0 -0
  119. data/spec/dummy/tmp/storage/4b/qe/4bqe6i8rtzlu196bvama05xnumrb +0 -0
  120. data/spec/dummy/tmp/storage/4n/9p/4n9pgwj5byodmx46ffhpvlydbrmh +0 -0
  121. data/spec/dummy/tmp/storage/4t/86/4t862kv9wcz0p7wgdvpmtmczdadt +0 -0
  122. data/spec/dummy/tmp/storage/4t/ke/4tkejzaafw2hopionhrbemj6jrij +0 -0
  123. data/spec/dummy/tmp/storage/4u/gx/4ugxo9x3cqbwg3d58u13xmtgc6f6 +0 -0
  124. data/spec/dummy/tmp/storage/57/kn/57kn4d3oyb3uqr0y0hwq4wl4d80i +0 -0
  125. data/spec/dummy/tmp/storage/5j/ls/5jlsuxajthpnn769oy836amrsavi +0 -0
  126. data/spec/dummy/tmp/storage/5n/ys/5nyszrcfj6fl2spwxjn1yea42ax0 +0 -0
  127. data/spec/dummy/tmp/storage/5s/zb/5szbksq6mg3768g9vtk788gc49gw +0 -0
  128. data/spec/dummy/tmp/storage/5y/zf/5yzft7e8r6cz5pcu78z6jj8dhmbz +0 -0
  129. data/spec/dummy/tmp/storage/62/jx/62jxz09uvpyv1okycwh7mv6z0gz5 +0 -0
  130. data/spec/dummy/tmp/storage/66/ed/66edq851b58dvses2okkafxtn827 +0 -0
  131. data/spec/dummy/tmp/storage/6a/8k/6a8k0jyqprv0z2q3a0p9bwiyy8av +0 -0
  132. data/spec/dummy/tmp/storage/6d/4e/6d4eiwu6oegnp12mwt27bwhkxe8v +0 -0
  133. data/spec/dummy/tmp/storage/6g/dc/6gdc40iivivwbln1zs4dqedt5ni7 +0 -0
  134. data/spec/dummy/tmp/storage/6m/ry/6mrynv03esjb64ohdo4q4xd0wr6t +0 -0
  135. data/spec/dummy/tmp/storage/6o/7a/6o7ax3ihg25bswxp4d601mqo7tl3 +0 -0
  136. data/spec/dummy/tmp/storage/6w/uj/6wujip3kahx619bqpcc4myv7tz5n +0 -0
  137. data/spec/dummy/tmp/storage/6z/86/6z862zpc67sikzl0otbf418t2clj +0 -0
  138. data/spec/dummy/tmp/storage/70/pb/70pbs8mjus3udsitby6gasexg4qz +0 -0
  139. data/spec/dummy/tmp/storage/71/rq/71rqssbyrwzhseipt1ojj2aucm2f +0 -0
  140. data/spec/dummy/tmp/storage/74/nt/74ntaj9azigfadsry359nl8jwbva +0 -0
  141. data/spec/dummy/tmp/storage/76/qk/76qkxksbv7v7meswa7mcnshr777l +0 -0
  142. data/spec/dummy/tmp/storage/7g/z0/7gz0olv00p0i3xqdy3f4fa6e73u2 +0 -0
  143. data/spec/dummy/tmp/storage/82/zv/82zvnds6te3el62i8vxv8rzkc4ms +0 -0
  144. data/spec/dummy/tmp/storage/83/b1/83b1ejivo3bxawg0kv4f1jufwarp +0 -0
  145. data/spec/dummy/tmp/storage/84/xr/84xr5dqonkroxjj0nkf3cznat5qt +0 -0
  146. data/spec/dummy/tmp/storage/8q/oh/8qohqcrf9fh6oc374ewp0lxid5lf +0 -0
  147. data/spec/dummy/tmp/storage/8v/yv/8vyvd9q13xzmav17gvu5tr1mvlws +0 -0
  148. data/spec/dummy/tmp/storage/91/35/9135ona6a51xpv669i6wz75kz8pr +0 -0
  149. data/spec/dummy/tmp/storage/92/hw/92hw9u9j6728qgwpcn7oqphe9tzj +0 -0
  150. data/spec/dummy/tmp/storage/9a/3q/9a3qd5qc7j6dzzmg16wcpvwoowmp +0 -0
  151. data/spec/dummy/tmp/storage/9b/2w/9b2w9oc0quy4lsa7y4zvvq8pfnh5 +0 -0
  152. data/spec/dummy/tmp/storage/9p/cd/9pcdjfvbqndd5dxue0ttlfeew1ht +0 -0
  153. data/spec/dummy/tmp/storage/al/8s/al8szf81ccm4ckpvxh3bv6vlgp0y +0 -0
  154. data/spec/dummy/tmp/storage/ao/tx/aotxomcc2m5ojywmr335fc27br55 +0 -0
  155. data/spec/dummy/tmp/storage/as/3k/as3k29j61efclm810sdnopepmgl2 +0 -0
  156. data/spec/dummy/tmp/storage/b0/wa/b0wa1zer7y7x8udydx3puofxd3fd +0 -0
  157. data/spec/dummy/tmp/storage/b8/8l/b88ln7wuq13v4akgwgc0dgac8887 +0 -0
  158. data/spec/dummy/tmp/storage/bb/iy/bbiyfh0r4f3szj4bmfwp7ptcst6k +0 -0
  159. data/spec/dummy/tmp/storage/bg/h0/bgh0cuyn7744wfbm8zuob9lugpxu +0 -0
  160. data/spec/dummy/tmp/storage/bi/6q/bi6qcv9yadwuy9au0q4vojvtqibp +0 -0
  161. data/spec/dummy/tmp/storage/bm/s6/bms684574m329zo33bmdzw4y05q8 +0 -0
  162. data/spec/dummy/tmp/storage/bn/8g/bn8gi5i69ysnnedgg57lg6r48hc0 +0 -0
  163. data/spec/dummy/tmp/storage/bp/0h/bp0hrk5xcf4q8q4b4ypo17ngqy93 +0 -0
  164. data/spec/dummy/tmp/storage/bs/y9/bsy9t4961ra8hwlq06wjtgrrcflp +0 -0
  165. data/spec/dummy/tmp/storage/ca/u3/cau32ihv1n1onmqmxf9pbpvwwp42 +0 -0
  166. data/spec/dummy/tmp/storage/ck/1p/ck1pqdlwjggav333jasfbrtptqs8 +0 -0
  167. data/spec/dummy/tmp/storage/ck/nb/cknbno5x3oh0nzvrry51ai2c2ce9 +0 -0
  168. data/spec/dummy/tmp/storage/cp/xd/cpxd4pz21lel4kv0463co0i34dyo +0 -0
  169. data/spec/dummy/tmp/storage/cq/25/cq25o59ipbdrfn01mtjvi5dwc8v0 +0 -0
  170. data/spec/dummy/tmp/storage/cq/os/cqosgu11l61u6gdz0c54mr4hasry +0 -0
  171. data/spec/dummy/tmp/storage/cs/x9/csx9mv26ab1lm82a7itryfq4v6rq +0 -0
  172. data/spec/dummy/tmp/storage/d5/aa/d5aag1rh6b9stocz1m1pg5c8mnfw +0 -0
  173. data/spec/dummy/tmp/storage/dm/c1/dmc1zx12pfl41f9br9f1l86953ew +0 -0
  174. data/spec/dummy/tmp/storage/dp/0f/dp0fx9ji1bqvx1najwjgns6n7fhf +0 -0
  175. data/spec/dummy/tmp/storage/dq/04/dq04jlw82vqiecdsxyrspe3y8zhd +0 -0
  176. data/spec/dummy/tmp/storage/dq/p8/dqp8o7eqfob92n81thzhj4mmviwf +0 -0
  177. data/spec/dummy/tmp/storage/dr/1z/dr1z3xxvya5ywessdrhmk05b2apz +0 -0
  178. data/spec/dummy/tmp/storage/dr/6z/dr6z0vwwsxqzw0kfkwl598uciyft +0 -0
  179. data/spec/dummy/tmp/storage/dx/iu/dxiu87gi66esp528s27d805z6b1v +0 -0
  180. data/spec/dummy/tmp/storage/e2/uo/e2uoyhzlaj5538p6rjs37pbl0z9g +0 -0
  181. data/spec/dummy/tmp/storage/ef/ih/efihy3gyspz150a8mpmhvj01xr07 +0 -0
  182. data/spec/dummy/tmp/storage/ej/20/ej20a2w7j929ut3zwo0kk5zyzp96 +0 -0
  183. data/spec/dummy/tmp/storage/ek/3j/ek3jzmz9919dhom6hbmhglq7e64b +0 -0
  184. data/spec/dummy/tmp/storage/em/kc/emkc4tc71k65mfcurv6k8z1ylswl +0 -0
  185. data/spec/dummy/tmp/storage/em/vx/emvx0c15o74mr0nlcvdc7m88j2gi +0 -0
  186. data/spec/dummy/tmp/storage/ew/n0/ewn0vyho1jbc7i76nat14codqc38 +0 -0
  187. data/spec/dummy/tmp/storage/f8/hf/f8hf7vk5c1h8s3upvdsgqbrdkokl +0 -0
  188. data/spec/dummy/tmp/storage/fo/9s/fo9s4w4egoj3qjbwknubsr4m3hca +0 -0
  189. data/spec/dummy/tmp/storage/fq/m7/fqm72ukjmyc0t6mgh73ehovlhm7i +0 -0
  190. data/spec/dummy/tmp/storage/ga/7e/ga7eiyyv0llme2i4xby0kdp4a4h8 +0 -0
  191. data/spec/dummy/tmp/storage/gc/bb/gcbbnsf6rq5xftpvxt4vfo39v2tx +0 -0
  192. data/spec/dummy/tmp/storage/gc/nn/gcnnb8yfz775d91vymz929zy2b7l +0 -0
  193. data/spec/dummy/tmp/storage/gv/kd/gvkd1h6f6qqh334ybfn71lwi6xk0 +0 -0
  194. data/spec/dummy/tmp/storage/gy/t2/gyt2tfjun5ezlgnl6u2ozz2s5wt9 +0 -0
  195. data/spec/dummy/tmp/storage/h0/i7/h0i7pyghnhpzsss74tk1k9k69yo4 +0 -0
  196. data/spec/dummy/tmp/storage/h4/86/h486d2xris442m90oylhhdlj1pjg +0 -0
  197. data/spec/dummy/tmp/storage/h4/vg/h4vgoatz21dhjrztrrbg2hdhkwjb +0 -0
  198. data/spec/dummy/tmp/storage/h5/13/h513cys269xn45jdhxhfyjlq5b3q +0 -0
  199. data/spec/dummy/tmp/storage/hb/yf/hbyf2wemy2azh7k1qhn3to9cpbj1 +0 -0
  200. data/spec/dummy/tmp/storage/hi/9h/hi9ho77symoy2j0ye28fxgnxw3kt +0 -0
  201. data/spec/dummy/tmp/storage/hl/yy/hlyyu150rt2yos1sa9ed1qw49y26 +0 -0
  202. data/spec/dummy/tmp/storage/hm/la/hmlataprq9fsh3126h6zmi19u2u1 +0 -0
  203. data/spec/dummy/tmp/storage/hp/6k/hp6kbroei8cm1chsl2bxhrpbkh1s +0 -0
  204. data/spec/dummy/tmp/storage/hr/mb/hrmb0w1dnyo6750fj1866f5np7sm +0 -0
  205. data/spec/dummy/tmp/storage/i9/6r/i96r6te3tutbwgxgl0maf3tgud51 +0 -0
  206. data/spec/dummy/tmp/storage/ih/xa/ihxalwtv9q6k97ryw0x3di5or5xw +0 -0
  207. data/spec/dummy/tmp/storage/in/jg/injgf3gi3v8yhpjwy4h8s96k0w8x +0 -0
  208. data/spec/dummy/tmp/storage/ir/zq/irzqn6i8886usqy6bcnsghmr01kg +0 -0
  209. data/spec/dummy/tmp/storage/iw/19/iw191t6h61ig4a68n3rk73vjvldc +0 -0
  210. data/spec/dummy/tmp/storage/j0/jz/j0jz8g89xbvv61ou1cj7dztym5k3 +0 -0
  211. data/spec/dummy/tmp/storage/j6/ym/j6ymkvvvhcdf7snmc6cardtsy9nd +0 -0
  212. data/spec/dummy/tmp/storage/j7/6x/j76x0oirv7i4t6p3blseuaknp7pw +0 -0
  213. data/spec/dummy/tmp/storage/jq/95/jq95rqhv5usgucn2d2mmkhjufapu +0 -0
  214. data/spec/dummy/tmp/storage/jr/uw/jruwp015m0chh50nxgkklum2ta3u +0 -0
  215. data/spec/dummy/tmp/storage/jz/ku/jzku30iopsxhh5quij3dov92vpyd +0 -0
  216. data/spec/dummy/tmp/storage/k0/wi/k0wijnkceisaxvkmc3hbr4croete +0 -0
  217. data/spec/dummy/tmp/storage/kk/76/kk76rr3nfbi1r4cmw9rcxuorpv4y +0 -0
  218. data/spec/dummy/tmp/storage/kn/z4/knz4o9yqqnipvbbo2fum9sz2528v +0 -0
  219. data/spec/dummy/tmp/storage/ky/1y/ky1ys68lmat11bxs2395dqugiyig +0 -0
  220. data/spec/dummy/tmp/storage/kz/4h/kz4hr1f97wfp44jkt5i3tvheo2hm +0 -0
  221. data/spec/dummy/tmp/storage/l4/ge/l4gelxdup4epl7lv9x5qyhatk2l6 +0 -0
  222. data/spec/dummy/tmp/storage/l5/3j/l53jq75i2ywyslq3wl999vl2jmyz +0 -0
  223. data/spec/dummy/tmp/storage/la/a6/laa6ye8vmuyl7m1gjpkcx19cdpzq +0 -0
  224. data/spec/dummy/tmp/storage/li/di/lidigrxrlew69ebcfx5ubeb203ck +0 -0
  225. data/spec/dummy/tmp/storage/ln/0f/ln0fz4opsdycu80q7urfez9ar7kn +0 -0
  226. data/spec/dummy/tmp/storage/lr/6l/lr6lqlqemfz0aorfbyot2lo9ck4o +0 -0
  227. data/spec/dummy/tmp/storage/lu/no/lunox74fm54ctc4qbfo2lj9l56sv +0 -0
  228. data/spec/dummy/tmp/storage/lv/o6/lvo6jno7mebvf0hssv20pgwfyum6 +0 -0
  229. data/spec/dummy/tmp/storage/m0/tm/m0tml6mrt7hiab73wgr0m9kaizn6 +0 -0
  230. data/spec/dummy/tmp/storage/mg/z6/mgz6nnkcl4j37w3ev6yolkfxe95o +0 -0
  231. data/spec/dummy/tmp/storage/mk/4w/mk4w528bsn47ewri0odui9s40f87 +0 -0
  232. data/spec/dummy/tmp/storage/ms/l9/msl9xauqjm3xnmfpxuiccmznlvnr +0 -0
  233. data/spec/dummy/tmp/storage/mu/ln/muln4ptnkbcff0s2p54j36goygbx +0 -0
  234. data/spec/dummy/tmp/storage/na/6r/na6rrohinrnjofsq27u95up5rp8k +0 -0
  235. data/spec/dummy/tmp/storage/nd/9y/nd9yeusukf9brbkzbm7af1yygidd +0 -0
  236. data/spec/dummy/tmp/storage/nf/sp/nfspv0s1uw5xo4qtxd8vsvvqy9v7 +0 -0
  237. data/spec/dummy/tmp/storage/nr/f9/nrf9wi6n0guazfp9gluc36do0dx1 +0 -0
  238. data/spec/dummy/tmp/storage/nw/le/nwle0hzkvkdl27fqqtm4nmpgzcvp +0 -0
  239. data/spec/dummy/tmp/storage/nx/64/nx64klyyxu3u3qz5lov4zf23fgco +0 -0
  240. data/spec/dummy/tmp/storage/nz/kd/nzkd3xlsbohxa2dgfyrz26iqb723 +0 -0
  241. data/spec/dummy/tmp/storage/o6/xf/o6xfczmxpom0laekvp59gute2p5d +0 -0
  242. data/spec/dummy/tmp/storage/oc/f8/ocf8zs18lm9fnkpqj6wpshdpyf43 +0 -0
  243. data/spec/dummy/tmp/storage/oc/xk/ocxkae9a9kkycvpfw71sdhnpqn85 +0 -0
  244. data/spec/dummy/tmp/storage/oe/bq/oebq593a6bpwkbxpx6segtwyy0jy +0 -0
  245. data/spec/dummy/tmp/storage/p5/4w/p54wycc6tln36b54yfsz2zk7hcdt +0 -0
  246. data/spec/dummy/tmp/storage/p9/hd/p9hddsr7pgksgl6vuqgtkp1ad7x2 +0 -0
  247. data/spec/dummy/tmp/storage/ph/va/phvajdvl6g28vluah7d38rpaj2el +0 -0
  248. data/spec/dummy/tmp/storage/pi/4i/pi4izeatwyrz6e8zdwvri4f4h4tl +0 -0
  249. data/spec/dummy/tmp/storage/pu/rl/purlhr67132j7c4k548memz2w2q1 +0 -0
  250. data/spec/dummy/tmp/storage/pv/bo/pvboa7wami2p1zjkuytzj9epmj14 +0 -0
  251. data/spec/dummy/tmp/storage/q5/i8/q5i8dg12fdmm5jura53gaw3zj6u4 +0 -0
  252. data/spec/dummy/tmp/storage/qn/1h/qn1hgmvsrnd8dkn4nvcyvqy3q2sb +0 -0
  253. data/spec/dummy/tmp/storage/qp/hi/qphia48836lod6l2ao5ca6ocd8ws +0 -0
  254. data/spec/dummy/tmp/storage/qs/jk/qsjkqiiarr85uobud0qsnnmpraol +0 -0
  255. data/spec/dummy/tmp/storage/qw/7z/qw7zsf91njf7ga6454nrjpvddjn5 +0 -0
  256. data/spec/dummy/tmp/storage/r6/6f/r66f8sxtwvlk8c1ava46bgua5hn0 +0 -0
  257. data/spec/dummy/tmp/storage/ra/6b/ra6b797wpupx6nqkgne3d63j6lh2 +0 -0
  258. data/spec/dummy/tmp/storage/ra/s0/ras0iwcg9lufnjah5yxyola73jsk +0 -0
  259. data/spec/dummy/tmp/storage/rd/e4/rde4tqu10zhrceb4uvvorhse4itt +0 -0
  260. data/spec/dummy/tmp/storage/rh/0h/rh0h80b8er9vp1u8dcocy1u58obf +0 -0
  261. data/spec/dummy/tmp/storage/ro/wb/rowb68g2iif1e8hsbjdjsmxj94h7 +0 -0
  262. data/spec/dummy/tmp/storage/s1/22/s122jwsnbcabv9fxp54nhoaaf34u +0 -0
  263. data/spec/dummy/tmp/storage/s6/on/s6onn1pu2bxcdkeebeu9qaht8i4d +0 -0
  264. data/spec/dummy/tmp/storage/s8/o0/s8o0enbem94835cqjla6onwncqpz +0 -0
  265. data/spec/dummy/tmp/storage/s9/lw/s9lwslyf5co34pvbt3n9ay06ui2w +0 -0
  266. data/spec/dummy/tmp/storage/sb/bo/sbboin8iacxsa7ywl1xp401f7tmj +0 -0
  267. data/spec/dummy/tmp/storage/sd/he/sdhe8pgaioyf7kdmdok21dy8enr3 +0 -0
  268. data/spec/dummy/tmp/storage/si/24/si24loctkg3h900v6vaoxwnruih7 +0 -0
  269. data/spec/dummy/tmp/storage/st/hv/sthv2tx2r8zv6tyn9yxi5am0pgzh +0 -0
  270. data/spec/dummy/tmp/storage/su/ng/sungqllfkjesc0p9c8hz3y2ior41 +0 -0
  271. data/spec/dummy/tmp/storage/sy/wq/sywqphj8vgv0imntn38s286yjjc3 +0 -0
  272. data/spec/dummy/tmp/storage/ta/s3/tas35nm4h81nhaecpeybk8kxzt62 +0 -0
  273. data/spec/dummy/tmp/storage/tc/gu/tcgurel05x9fk9ksm4hxwfla3hg3 +0 -0
  274. data/spec/dummy/tmp/storage/tk/rt/tkrtpgn5p68rqy679q15ab3j7twz +0 -0
  275. data/spec/dummy/tmp/storage/tm/ce/tmce54998rdnz191k02fzowpebvw +0 -0
  276. data/spec/dummy/tmp/storage/tt/pu/ttpumlt7wi54pohcc7ktsl5le777 +0 -0
  277. data/spec/dummy/tmp/storage/u1/vf/u1vfyawqqy7wpkthgardxs358car +0 -0
  278. data/spec/dummy/tmp/storage/u2/xa/u2xaxpjz4fdxtxxinaxq2r7biovv +0 -0
  279. data/spec/dummy/tmp/storage/uf/67/uf67aznvgtom02vj8q4jl60hycfm +0 -0
  280. data/spec/dummy/tmp/storage/ui/xi/uixi7xtks88zuqr4gwi6cjbk4m47 +0 -0
  281. data/spec/dummy/tmp/storage/uq/jk/uqjkltli1s6vz51g6yu551ze48c1 +0 -0
  282. data/spec/dummy/tmp/storage/ux/te/uxtezp2rqztn4cernmn7477gukxe +0 -0
  283. data/spec/dummy/tmp/storage/v4/yi/v4yieu5kcx0jz3ephiptzr46djev +0 -0
  284. data/spec/dummy/tmp/storage/va/sc/vascc4h0c7dv7uwwcn2wdvx6qyhy +0 -0
  285. data/spec/dummy/tmp/storage/vp/ub/vpub3n9dk3ts14cvq9tvkez7crqq +0 -0
  286. data/spec/dummy/tmp/storage/w2/3f/w23f3igzkn7bddqxry5x4wsu2ths +0 -0
  287. data/spec/dummy/tmp/storage/w4/1j/w41judbhn1j3quwhs36myqwnypkz +0 -0
  288. data/spec/dummy/tmp/storage/w4/d3/w4d3qfnguynfuw4oxo5hek8q5w66 +0 -0
  289. data/spec/dummy/tmp/storage/w9/na/w9na14949rr42w928n9srevxecbl +0 -0
  290. data/spec/dummy/tmp/storage/wo/81/wo813rsnwvoa55h0vq0fr79iajuw +0 -0
  291. data/spec/dummy/tmp/storage/wp/zs/wpzs5finp3t36za2bykcoxueu5b6 +0 -0
  292. data/spec/dummy/tmp/storage/wv/9t/wv9t3gxm6dqah7kdq74pimjdb156 +0 -0
  293. data/spec/dummy/tmp/storage/ww/40/ww40d8rykhlpxwfh0ggfs7mrh0jl +0 -0
  294. data/spec/dummy/tmp/storage/wy/14/wy14megn3o5zqplv9xg6u32uwkr6 +0 -0
  295. data/spec/dummy/tmp/storage/xd/4h/xd4h96rdmw5t9pujgz831cnfgj8o +0 -0
  296. data/spec/dummy/tmp/storage/xi/en/xiensi0706n8m0x5lxp0fbwg8ipk +0 -0
  297. data/spec/dummy/tmp/storage/xj/yy/xjyygdd3znvvpt9ufz1vv4lfsx3w +0 -0
  298. data/spec/dummy/tmp/storage/xs/x1/xsx109k9pb83qze3raurxo22dnms +0 -0
  299. data/spec/dummy/tmp/storage/xv/gf/xvgf6x0othqxlxcbgwz4sg7th3p9 +0 -0
  300. data/spec/dummy/tmp/storage/y5/3g/y53gv7ysx4j1y0k71pszym8sdu6b +0 -0
  301. data/spec/dummy/tmp/storage/ya/yf/yayfpxlrbtz0578nl9tlourrwe27 +0 -0
  302. data/spec/dummy/tmp/storage/yd/x8/ydx8jm52rnl3b7mpvmmxlilenllw +0 -0
  303. data/spec/dummy/tmp/storage/ye/bu/yebu3imdihqdatzktkubhkto82xo +0 -0
  304. data/spec/dummy/tmp/storage/yf/49/yf49a4ydheqf3cqs0u49sanbl4ms +0 -0
  305. data/spec/dummy/tmp/storage/yh/q1/yhq1muao2dpuykmj12bxhd0x4ntk +0 -0
  306. data/spec/dummy/tmp/storage/ym/5n/ym5ndg2m03vfnoeryvb9tex8xj72 +0 -0
  307. data/spec/dummy/tmp/storage/yx/jp/yxjpumjyo1jysjpg20qaxgsqg4fw +0 -0
  308. data/spec/dummy/tmp/storage/z1/gr/z1grp34d5vw7mi4g8vw8yfu91ny2 +0 -0
  309. data/spec/dummy/tmp/storage/z5/qs/z5qs5fq00igr3xv5izgcyhhsdw7y +0 -0
  310. data/spec/dummy/tmp/storage/z5/sg/z5sgd1au9gcfkqb3kq82f3yry6a6 +0 -0
  311. data/spec/dummy/tmp/storage/z7/8n/z78nuzozxx53c7cpp3e4kt3nghaa +0 -0
  312. data/spec/dummy/tmp/storage/zk/3v/zk3vlz1al2rba9wlkzoa6p8wpli0 +0 -0
  313. data/spec/dummy/tmp/storage/zk/xs/zkxsr1zywhaydz0cep4eh8mmos46 +0 -0
  314. data/spec/dummy/tmp/storage/zx/ur/zxuraz59df480azmknqbfeb37ktm +0 -0
  315. data/spec/examples.txt +126 -0
  316. data/spec/factories/snf_core/addresses.rb +10 -0
  317. data/spec/factories/snf_core/business_documents.rb +18 -0
  318. data/spec/factories/snf_core/businesses.rb +10 -0
  319. data/spec/factories/snf_core/categories.rb +7 -0
  320. data/spec/factories/snf_core/customer_groups.rb +9 -0
  321. data/spec/factories/snf_core/delivery_orders.rb +36 -0
  322. data/spec/factories/snf_core/groups.rb +6 -0
  323. data/spec/factories/snf_core/order_items.rb +9 -0
  324. data/spec/factories/snf_core/orders.rb +33 -0
  325. data/spec/factories/snf_core/products.rb +9 -0
  326. data/spec/factories/snf_core/roles.rb +5 -0
  327. data/spec/factories/snf_core/store_inventories.rb +8 -0
  328. data/spec/factories/snf_core/stores.rb +9 -0
  329. data/spec/factories/snf_core/user_roles.rb +6 -0
  330. data/spec/factories/snf_core/users.rb +12 -0
  331. data/spec/factories/snf_core/wallets.rb +7 -0
  332. data/spec/mailers/previews/snf_core/auth_mailer_preview.rb +6 -0
  333. data/spec/mailers/snf_core/auth_mailer_spec.rb +7 -0
  334. data/spec/models/snf_core/address_spec.rb +15 -0
  335. data/spec/models/snf_core/business_document_spec.rb +20 -0
  336. data/spec/models/snf_core/business_spec.rb +14 -0
  337. data/spec/models/snf_core/category_spec.rb +12 -0
  338. data/spec/models/snf_core/customer_group_spec.rb +11 -0
  339. data/spec/models/snf_core/delivery_order_spec.rb +70 -0
  340. data/spec/models/snf_core/group_spec.rb +11 -0
  341. data/spec/models/snf_core/order_item_spec.rb +64 -0
  342. data/spec/models/snf_core/order_spec.rb +81 -0
  343. data/spec/models/snf_core/product_spec.rb +17 -0
  344. data/spec/models/snf_core/role_spec.rb +12 -0
  345. data/spec/models/snf_core/store_inventory_spec.rb +24 -0
  346. data/spec/models/snf_core/store_spec.rb +13 -0
  347. data/spec/models/snf_core/user_role_spec.rb +11 -0
  348. data/spec/models/snf_core/user_spec.rb +22 -0
  349. data/spec/models/snf_core/wallet_spec.rb +28 -0
  350. data/spec/rails_helper.rb +46 -0
  351. data/spec/requests/snf_core/auth_spec.rb +139 -0
  352. data/spec/sample_spec.rb +5 -0
  353. data/spec/spec_helper.rb +36 -0
  354. data/spec/support/models/shared_examples.rb +49 -0
  355. data/spec/support/requests/shared_requests.rb +130 -0
  356. metadata +320 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83c5def24cd7020177eae6597f364a39841f9f5efbc1ea557088cf91a2e229f5
4
- data.tar.gz: 9d505259d18863a0e6764409245d8bb9a480fcc5feb7c5112231c81e25276b13
3
+ metadata.gz: 2ba7ee61a617e2f1740360b891c9445fc4085c217ef2a4b7b6ad516ff963439e
4
+ data.tar.gz: 3d9d5f1fb249faa10260f1cf212f4e298b4c592dfd82a90cc208d2f0004df4f8
5
5
  SHA512:
6
- metadata.gz: ad69aa4dd4b0d9c859f5e29b93f742b8df99763bfbad965e8a894cb7609969a785459714a6009ff4c55c9d80baa042ac17a803d8d600f4c5cb444afcc32c64a1
7
- data.tar.gz: 36e1e06fe3be561fac54d3822d92bea8439bd72444b7f3f2f06598646366ff2260b58520ee49c6e833917a6aaaf397d5beea44f14cc6cf0c77534d853f96efd6
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
- business_license: 0,
8
- representative_id: 1
9
- }, suffix: :doc
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
@@ -0,0 +1,8 @@
1
+ module SnfCore
2
+ class Role < ApplicationRecord
3
+ has_many :user_roles, dependent: :destroy
4
+ has_many :users, through: :user_roles
5
+
6
+ validates :name, presence: true, uniqueness: true
7
+ end
8
+ end
File without changes
File without changes
@@ -1,18 +1,18 @@
1
- module SnfCore
2
- class User < ApplicationRecord
3
- has_one :wallet, dependent: :destroy
4
-
5
- validates :first_name, :middle_name, :last_name, :phone_number, :role, presence: true
6
- validates :phone_number, :email, uniqueness: true
7
-
8
- enum :role, { admin: 0, wholesaler: 1, retailer: 2, consumer: 3 }
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
@@ -0,0 +1,6 @@
1
+ module SnfCore
2
+ class UserRole < ApplicationRecord
3
+ belongs_to :user
4
+ belongs_to :role
5
+ end
6
+ 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,2 +1,7 @@
1
1
  SnfCore::Engine.routes.draw do
2
+ post "auth/login"
3
+ post "auth/reset_password_request"
4
+ post "auth/reset_password"
5
+ post "auth/change_password"
6
+
2
7
  end
@@ -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
- t.integer :role, null: false
10
-
11
- t.timestamps
12
- end
13
- end
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
@@ -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,9 @@
1
+ class CreateSnfCoreRoles < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :snf_core_roles do |t|
4
+ t.string :name, null: false
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ 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
File without changes
@@ -1,3 +1,3 @@
1
1
  module SnfCore
2
- VERSION = "0.2.8"
2
+ VERSION = "0.2.92"
3
3
  end
data/lib/snf_core.rb CHANGED
File without changes
File without changes