Skip to content

rollvolet/pricelist-export-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pricelist export service

Export products and price info to a CSV-file. Task-based execution, triggered by delta messages. Uses the RPIO Task model.

Based on following SPARQL-query:

PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX dct: <http://purl.org/dc/terms/>
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX pricing: <http://data.rollvolet.be/vocabularies/pricing/>
PREFIX stock: <http://data.rollvolet.be/vocabularies/stock-management/>
PREFIX schema: <http://schema.org/>
SELECT ?id ?category ?subcategory ?name ?supplier ?ikp ?ikpUnit ?vkp ?vkpIncl ?margin ?vkpBase ?vkpUnit ?department WHERE {
GRAPH ?g {
?s a gr:SomeItems ;
gr:name ?name ;
dct:identifier ?id ;
ext:purchaseOffering ?purchase ;
ext:salesOffering ?sales .
OPTIONAL {
?s gr:category ?subcategoryUri .
?subcategoryUri skos:prefLabel ?subcategory .
OPTIONAL {
?subcategoryUri skos:broader/skos:prefLabel ?category .
}
}
OPTIONAL {
?purchase ^gr:offers/gr:name ?supplier ;
gr:hasPriceSpecification ?priceIn .
OPTIONAL {
?priceIn gr:hasCurrencyValue ?ikp .
}
OPTIONAL {
?priceIn gr:hasUnitOfMeasurement/skos:prefLabel ?ikpUnit .
}
}
OPTIONAL {
?sales gr:hasPriceSpecification ?priceOut .
?priceOut gr:valueAddedTaxIncluded "true"^^<http://mu.semte.ch/vocabularies/typed-literals/boolean> .
OPTIONAL {
?priceOut gr:hasCurrencyValue ?vkpIncl .
}
OPTIONAL {
?priceOut pricing:margin ?margin .
}
OPTIONAL {
?priceOut pricing:calculationBasis ?calc .
?calc skos:prefLabel ?vkpBase .
}
OPTIONAL {
?priceOut gr:hasUnitOfMeasurement/skos:prefLabel ?vkpUnit .
}
}
OPTIONAL {
?s stock:location/stock:department/schema:name ?department .
}
BIND(IF(BOUND(?vkpIncl), ?vkpIncl * 100 / (100 + ${VAT_RATE}), 0) as ?vkp)
}
} ORDER BY ?category ?subcategory ?id

Example configuration

docker-compose.yml

  pricelist-export:
    image: semtech/mu-javascript-template:1.8.0
    volumes:
      - /home/michael/rpio/projects/ROLL/pricelist-export-service:/app
      - ./data/files:/share
    environment:
      NODE_ENV: "development"
    restart: always
    logging: *default-logging
    labels:
      - "logging=true"

config/delta/rules.js

  {
    match: {
      predicate: {
        type: "uri",
        value: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
      },
      object: {
        type: "uri",
        value: "http://redpencil.data.gift/vocabularies/tasks/Task",
      },
    },
    callback: {
      url: "http://pricelist-export/delta",
      method: "POST"
    },
    options: {
      resourceFormat: "v0.0.1",
      gracePeriod: 500,
      ignoreFromSelf: true
    }
  },

config/authorization/config.ex

      %GroupSpec{
        name: "rollvolet-write",
        useage: [:read, :write, :read_for_write],
        access: authenticated_access(),
        graphs: [
          %GraphSpec{
            graph: "http://mu.semte.ch/graphs/rollvolet",
            constraint: %ResourceConstraint{
              resource_types: [
                ...
                "http://redpencil.data.gift/vocabularies/tasks/Task"
              ]
            }
          }
        ]

config/resource/task.lisp

(define-resource task ()
  :class (s-prefix "task:Task")
  :properties `((:created :datetime ,(s-prefix "dct:created"))
                (:modified :datetime ,(s-prefix "dct:modified"))
                (:status :url ,(s-prefix "adms:status"))
                (:operation :url ,(s-prefix "task:operation"))
                (:index :string ,(s-prefix "task:index")))
  :has-many `((task :via ,(s-prefix "cogs:dependsOn")
                    :as "parent-tasks"))
  :has-one `((data-container :via ,(s-prefix "task:resultContainer")
                   :as "result-container")
             (data-container :via ,(s-prefix "task:inputContainer")
                   :as "input-container")
             )
  :resource-base (s-url "http://data.rollvolet.be/tasks/")
  :features '(include-uri)
  :on-path "tasks")

(define-resource data-container ()
  :class (s-prefix "nfo:DataContainer")
  :has-one `((task :via ,(s-prefix "task:resultContainer")
                    :inverse t
                    :as "result-from-tasks")
              (task :via ,(s-prefix "task:inputContainer")
                    :inverse t
                    :as "input-from-tasks"))
  :has-many `((file :via ,(s-prefix "ext:content")
                    :as "files")
              )
  :resource-base (s-url "http://data.rollvolet.be/data-containers/")
  :features '(include-uri)
  :on-path "data-containers")

config/dispatcher/dispatcher.ex

  match "/tasks/*path", @json_service do
    Proxy.forward conn, path, "http://cache/tasks/"
  end

  match "/data-containers/*path", @json_service do
    Proxy.forward conn, path, "http://cache/data-containers/"
  end