Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

iunu/apps-cannapis

Repository files navigation

Artemis / Metrc Integration

Artemis' integration service for Metrc.

Things you may want to cover:

  • Ruby version: v2.6.5

  • System dependencies:

    • Docker.
    • docker-compose
    • Ruby v2.6.5
    • bundler v2.
    • If you use Mac, and don't wish to install Postgres locally, run bundle config --local build.pg --with-opt-dir="/usr/local/opt/libpq" on your shell.
  • Database creation: docker compose takes care of creating the database and performing migrations for you.

  • Create Testing Database: create a new pgsql user using credentials in database.yml test: then run RAILS_ENV=test bundle exec rails db:create

  • How to run the test suite: bundle exec rspec or bundle exec guard.

  • Services: the application uses Sidekiw, along with Redis, in order to run background jobs. Locally, docker-compose takes care of creating and running these instances for you.

  • Deployment instructions: push to master, and let the Heroku integration do it for you.

  • How to start: simply run docker-compose up --build and grab a cup a coffee.

Metrc state-endpoint payloads

Op. Endpoint MD OH MA CO OR MT
Seed POST /plantbatches/v1/createplantings [{"Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }] [{ "Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }] [{ "Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }] [{ "Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }] [{ "Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }] [{ "Name": <tracking-code>, "Type": <seeding-unit-name>, "Count": <batch-quantity>, "Strain": <batch-crop-variety>, "Room": <batch-zone-name>, "PatientLicenseNumber": null, "ActualDate": <batch-seeded_at> }]
Move (PB) PUT /plantbatches/v1/moveplantbatches [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }] [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }] [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }] [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }] [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }] [{ "Name": <batch-arbitrary-id>, "Room": <completion-zone-name>, "MoveDate": <completion-start_time> }]
Move (CGP) POST /plantbatches/v1/changegrowthphase [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }] [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }] [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }] [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }] [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }] [{ "Name": <batch-arbitrary-id>, "Count": <batch-quantity>, "StartingTag": <first-item-barcode-id>, "GrowthPhase": <seeding-unit-name>, "NewRoom": <batch-zone-name>, "GrowthDate": <completion-start_time>, "PatientLicenseNumber": null }]
Move (MP) POST /plants/v1/moveplants [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }] [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }] [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }] [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }] [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }] [{ "Id": null, "Label": <item-barcode-id>, "Room": <completion-zone-name>, "ActualDate": <completion-start_time> }]
Discard (immature) POST /plantbatches/v1/destroy [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "PlantBatch": <batch-arbitrary-id>, "Count": <discard-quantity>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }]
Discard (mature/partial) POST /plants/v1/destroyplants [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <completion-barcode>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }]
Discard (mature/complete) POST /plants/v1/destroyplants [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }] [{ "Id": null, "Label": <item-barcode-id>, "ReasonNote": <discard-reason>, "ActualDate": <discard-discarded_at> }]
Harvest (manicure) POST /plants/v1/manicureplants [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": null }]
Harvest (complete) POST /plants/v1/harvestplants [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }] [{ "DryingRoom": <completion-zone_name>, "PatientLicenseNumber": null, "ActualDate": <completion-start_time>, "Plant": <item-barcode-id>, "Weight": <items-average-weight>, "UnitOfWeight": <item-secondary_harvest_unit>, "HarvestName": <batch-arbitrary-id> }]

Development

Syncing data from portal

There is a rake script which can be used to sync data from portal which can then be used for testing.

To sync:

  • ARTEMIS_ID=<artemis user ID> FACILITY_ID=<portal facility ID> BATCH_ID=<portal batch ID> rake artemis:data:sync

Currently the following is synced:

  • facility
  • facility/resource units (list and individually)
  • batch (with includes)
  • batch/completions
  • batch/items

Notification Mailer

If SEND_MAILS is set, then mails will be sent via Mailgun. If SEND_MAILS is not set, and if MAILTRAP_API_KEY is set, then mailers will be automatically configured to use Mailtrap for testing sending of emails.

Mails tests can be triggered via any of the following:

  • rake notifier:test
  • POST app-domain/v1/test_mailer
  • TaskRunner.simulate_failure