{"id":30578071,"url":"https://github.com/identitysquare/time_pricing","last_synced_at":"2025-08-29T03:03:23.923Z","repository":{"id":48157215,"uuid":"250227691","full_name":"IdentitySquare/time_pricing","owner":"IdentitySquare","description":"⏳💰 A gem to calculate pricing for a time based service, bookings or appointments.","archived":false,"fork":false,"pushed_at":"2023-03-17T02:40:00.000Z","size":64,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-26T13:05:07.472Z","etag":null,"topics":["calculator","cost","pricing","rails","ruby"],"latest_commit_sha":null,"homepage":"https://identitysquare.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IdentitySquare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-26T10:29:26.000Z","updated_at":"2023-11-06T17:30:38.000Z","dependencies_parsed_at":"2024-08-05T18:35:13.955Z","dependency_job_id":null,"html_url":"https://github.com/IdentitySquare/time_pricing","commit_stats":{"total_commits":66,"total_committers":5,"mean_commits":13.2,"dds":0.303030303030303,"last_synced_commit":"bbc51bd54cbd026a1c9cf50a3b3b037107bef6b9"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/IdentitySquare/time_pricing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IdentitySquare%2Ftime_pricing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IdentitySquare%2Ftime_pricing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IdentitySquare%2Ftime_pricing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IdentitySquare%2Ftime_pricing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IdentitySquare","download_url":"https://codeload.github.com/IdentitySquare/time_pricing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IdentitySquare%2Ftime_pricing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272617820,"owners_count":24965401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculator","cost","pricing","rails","ruby"],"created_at":"2025-08-29T03:01:46.178Z","updated_at":"2025-08-29T03:03:23.916Z","avatar_url":"https://github.com/IdentitySquare.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⏳💰 TimePricing\n\nCalculate time based pricing based on duration or start time + end time. Useful for services, bookings or appointments where pricing is based on duration. This can be used with repeating combination of plans or without combining plans.A set of plans can be entered in and this can be used to give you the best combination of plans for the timespan entered.\n\n## 🛠Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'time_pricing'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install time_pricing\n\n## ✅ Basic Usage Example\n\nInitialize the service, define available plans and query for price with a time range or duration.\n\n``` ruby\n# New pricing calculation\ntime_pricing = TimePricing.new\n\n# Add available plans\n\ntime_pricing.add_plan!({\n    name: 'per_hour',\n    duration: 1.hour, # duration in milliseconds\n    cost: 500 # €5.00 for an hour\n})\n\ntime_pricing.add_plan!({\n    name: 'per_day',\n    duration: 1.day,\n    cost: 2000 # €20.00 for 1 day\n})\n\n# Calculate with time ranges\n\ncost = time_pricing.for_time(Time.now, Time.now + 6.hours).cost\n\n# OR with duration\n\ncost = time_pricing.for_duration(6.hours).cost\n\nputs cost\n# =\u003e 2000\n# (€20.00 because 'per day' rate is cheaper than 6 * 'per hour' rate of €60.00 in total)\n```\n\n## 🛠 Options\n\n### Initializing\n\n``` ruby\nTimePricing.new({\n    combine_plans: true\n})\n```\n* `combine_plans` *(optional, default `true`)*: Set to `false` to not combine multiple plans to make up the duration. Each plan is only added with itself to make up the duration.\n\n### Adding a plan\n\n``` ruby\ntime_pricing.add_plan!({\n    name: 'per_hour',\n    duration: 1.hour,\n    cost: 2000\n})\n```\n\n* `name` *(required)*: a unique identifier for each plan\n* `duration` *(required)*: milliseconds of how long is this plan for\n* `cost` *(required)*: a positive integer representing how much to charge in the smallest currency unit (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency). Can be set to 0 for a free plan.\n\n### Removing a plan\n\n``` ruby\n# remove a plan with it's unique name\ntime_pricing.remove_plan!('per_day')\n```\n\n### Other methods\n``` ruby\n# a list of plans that are setup. Returns an array of plan objects\ntime_pricing.plans\n```\n\n### Calculating price\n\n``` ruby\ntime_pricing.for_time(Time.now, Time.now + 6.hours).cost\n```\n\n* `start_time` *(required)*: timestamp\n* `end_time` *(required)*: timestamp\n\n\n``` ruby\ntime_pricing.for_duration(6.hours).cost\n```\n\n* `duration` *(required)*\n\n### Calculation breakdown\nHow did we get to the final cost.\n\n``` ruby\ncalculation = time_pricing.for_duration(6.hours)\n\n# price in cents\ncalculation.cost\n\n# if using the for_time method\ncalculation.start_time\ncalculation.end_time\n\n# the requested duration for pricing\ncalculation.duration\n\n# Total duration (in milliseconds) the plans make up\ncalculation.total_duration\n\n# any extra duration (in milliseconds) than the requested\n# to make up for the requested duration\ncalculation.extra_duration\n\n# breakdown of how the cost was calculated and what plans were used\ncalculation.breakdown\n# [\n#    {\n#        start_time: \"\",\n#        end_time: \"\",\n#        duration: 0,\n#        name: \"per_day\",\n#        cost: 1000\n#    },\n#    {\n#        start_time: \"\",\n#        end_time: \"\",\n#        duration: 0,\n#        name: \"per_day\",\n#        cost: 1000\n#    },\n#    {...}\n# ]\n# start_time and end_time only appears if using for_time to calculate cost\n\n```\n\n## 🏎 Caching the combinations externally\n\nTimePricing uses cache to keep track of pricing that we have calculated already to speed up the going through all the combinations possible if `combine_plan: true`. This significantly speeds up the calculations. This can be saved externally from the gem and can be set for even faster look up /for the same plans/.\n\n\n``` ruby\n# Get the cache\n# Save this in your application's persisted cache\nsaved_cache = time_pricing.cache\n\n# Setting cache back for another session\nTimePricing.new({cache: saved_cache})\n```\n\n*Important:* Be sure to clear your externally saved cache if you add, remove or change plans.\n\n\n## ⚠️ Known Issues\n\nIf you have smaller duration plans and are looking for pricing for a large duration (approx. over 500 times the largest duration plan - which is a lot!), you might encounter `stack level too deep` error. Consider limiting the duration you query a pricing for.   \n\n\n## 🤓 Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/identitysquare/time_pricing. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n### Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the TimePricing project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/time_pricing/blob/master/CODE_OF_CONDUCT.md).\n\n## 🥳 Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Annajoe96\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/57370408?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAnna Joe\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/danielpaul\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/333233?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDaniel Paul\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/iJohnPaul\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/25507937?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJohn Paul\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidentitysquare%2Ftime_pricing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidentitysquare%2Ftime_pricing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidentitysquare%2Ftime_pricing/lists"}