GithubHelp home page GithubHelp logo

elmis-service's People

Contributors

dependabot[bot] avatar josh-griffin avatar mark-prins avatar wlthomson avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elmis-service's Issues

Login method

Method for authorizing with the eSigl interface.

Has to deal with setting of the cookie in the response. Could simply return the cookie, or a middleware could be written to globally set the cookie.

Error checking includes:

  • 401: Unauthorized. The username/password is incorrect.
  • 500: Server error.
  • Possibly: Checking the response body for permissions to continue. EG can create, update etc.

Should throw an error in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value will be dependent on how this is implemented.

POST Approve requisition

Method for attempting to approve a requisition given a requisitionId

NOTE: On catching an error, this method must attempt to delete the corresponding requisition before exiting.

error conditions:

  • 500: server error.
  • 401: unauthorized.

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be true on success.

Deleting requisitions on failure

When the service is called to create an order from a non existing requisition, many steps have to be taken. Create -> save -> submit -> authorize -> approve -> convert. If at any point one of these procedures fails, the requisition should be deleted from the eSIGL server so we don't need to track at what specific stage a requisition which has failed to be converted is left at.

One solution could be within the entry point of the module: Store a boolean or potentially an int: requisitionCreated which is set to true or to the ID of the created requisition on a successful call to createRequisition. On catching an error, if requisitionCreated = true/an id, a deleteRequisition call is made.

Potentially need a field in the errorObject indicating if the requisition has been deleted, or if the deleteRequisition call also failed.

The PR for this issue should contain a methoddeleteRequisition({cookie, baseURL, requisitionId }) which will delete the corresponding requisition.

Should use the endpoint /requisitions/delete/{requisitionId}.json - POST method, no JSON body

Program matching method

Method for matching the program code given from the input parameters to a program received from eSigl.

Error conditions:

  • There is no matching program.

Error should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be the programId of the matched program.

POST save requisition

Method to save a requisition in the eSigl system with an eSigl transformed object.

NOTE: eSigl will not try to validate the requisition at this point. No indication will be given by eSigl at this point if the requisition is malformed. If an error is thrown, we must delete the created requisition before continuing

Error conditions:

  • 500: Server error
  • 401: Unauthorized.

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be true on success

Entry point

Module entry point method for calling subsequent methods in order to:

  • verify parameters
  • find a matching programId for the given programCode
  • find a matching facilityId for the given facilityCode
  • create a requisition
  • updating and save a requisition
  • submit a requisition
  • authorize a requisition
  • approve a requisition
  • convert a requisition to an order

Return value will be either an error on any unsuccessful attempts (?), or a success object.

Requisition Merge: Correct fields

The input has changed which is coming from 4D.

{
   "ID":"80AC28F337804413B29B0832B0621047",
   "date_stock_take":"2019-02-28T11:00:00.000Z",
   "user_ID":"0763E2E3053D4C478E1E6B6B03FEC207",
   "name_ID":"861102F624354F15ABEB48DC207A4C2D",
   "status":"sg",
   "date_entered":"2019-02-28T11:00:00.000Z",
   "nsh_custInv_ID":"",
   "daysToSupply":90,
   "store_ID":"D77F67339BF8400886D009178F4962E1",
   "type":"request",
   "date_order_received":"0000-00-00T00:00:00.000Z",
   "previous_csh_id":"",
   "serial_number":8,
   "requester_reference":"",
   "comment":"",
   "colour":1,
   "custom_data":null,
   "linked_requisition_id":"",
   "linked_purchase_order_ID":"",
   "authorisationStatus":"",
   "thresholdMOS":0,
   "orderType":"",
   "periodID":"",
   "programID":"87027C44835B48E6989376F42A58F7E3",
   "Link_201":{
      "__KEY":"861102F624354F15ABEB48DC207A4C2D"
   },
   "user":{
      "__KEY":"0763E2E3053D4C478E1E6B6B03FEC207"
   },
   "store":{
      "ID":"D77F67339BF8400886D009178F4962E1",
      "name":"General Warehouse",
      "code":"C1426",
      "name_ID":"6F0EA445B35F479AA1020BD2D24B9755",
      "mwks_export_mode":"Single",
      "IS_HIS":false,
      "sort_issues_by_status_spare":false,
      "disabled":false,
      "responsible_user_ID":"",
      "organisation_name":"",
      "address_1":"",
      "address_2":"",
      "logo":"[object Picture]",
      "sync_id_remote_site":1,
      "address_3":"",
      "address_4":"",
      "address_5":"",
      "postal_zip_code":"",
      "store_mode":"store",
      "phone":"",
      "tags":"",
      "spare_user_1":"",
      "spare_user_2":"",
      "spare_user_3":"",
      "spare_user_4":"",
      "spare_user_5":"",
      "spare_user_6":"",
      "spare_user_7":"",
      "spare_user_8":"",
      "spare_user_9":"",
      "spare_user_10":"",
      "spare_user_11":"",
      "spare_user_12":"",
      "spare_user_13":"",
      "spare_user_14":"",
      "spare_user_15":"",
      "spare_user_16":"",
      "custom_data":null
   },
   "program":{
      "ID":"87027C44835B48E6989376F42A58F7E3",
      "description":"District Store",
      "date_created":"2017-08-16T12:00:00.000Z",
      "created_by_user_ID":"0763E2E3053D4C478E1E6B6B03FEC207",
      "note":"",
      "gets_new_items":false,
      "tags":null,
      "isProgram":false,
      "programSettings":{
         "code":"PNLSLAB"
      }
   },
   "requisitionLines":[
      {
         "ID":"9CE20BC692D9486DA598C7E219DB53E4",
         "requisition_ID":"80AC28F337804413B29B0832B0621047",
         "item_ID":"AA6A1FE8871D4058A84CED49DADD23A9",
         "stock_on_hand":1300,
         "actualQuan":0,
         "imprest_or_prev_quantity":0,
         "colour":-255,
         "line_number":1,
         "Cust_prev_stock_balance":0,
         "Cust_stock_received":0,
         "Cust_stock_order":0,
         "comment":"",
         "Cust_loss_adjust":0,
         "days_out_or_new_demand":0,
         "previous_stock_on_hand":0,
         "daily_usage":1.1111111111111,
         "suggested_quantity":0,
         "adjusted_consumption":0,
         "linked_requisition_line_ID":"",
         "purchase_order_line_ID":"",
         "item":{
            "ID":"AA6A1FE8871D4058A84CED49DADD23A9",
            "item_name":"Acetylsalicylic Acid 100mg tabs",
            "start_of_year_date":"0000-00-00T00:00:00.000Z",
            "manufacture_method":"",
            "default_pack_size":100,
            "dose_picture":"[object Picture]",
            "atc_category":"ANTI-ANGINAL",
            "medication_purpose":"",
            "instructions":"",
            "user_field_7":false,
            "flags":"",
            "ddd_value":"1",
            "code":"AR07112",
            "other_names":"",
            "type_of":"general",
            "price_editable":false,
            "margin":0,
            "barcode_spare":"3",
            "spare_ignore_for_orders":false,
            "sms_pack_size":0,
            "expiry_date_mandatory":false,
            "volume_per_pack":0,
            "department_ID":"",
            "weight":1,
            "essential_drug_list":true,
            "catalogue_code":"",
            "indic_price":0,
            "user_field_1":"",
            "spare_hold_for_issue":false,
            "builds_only":false,
            "reference_bom_quantity":0,
            "use_bill_of_materials":false,
            "description":"",
            "spare_hold_for_receive":false,
            "Message":"",
            "interaction_group_ID":"",
            "spare_pack_to_one_on_receive":false,
            "cross_ref_item_ID":"",
            "spare_shelf_location_bulk":"",
            "user_field_4":false,
            "user_field_6":"",
            "spare_internal_analysis":0,
            "user_field_2":"",
            "user_field_3":"",
            "ddd factor":1,
            "account_stock_ID":"52923505A91447B9923BA34A4F332014",
            "account_purchases_ID":"330ACC81721C4126BD5DD6769466C5C4",
            "account_income_ID":"EF34ADD07C014AB8914E30CA2E3FEA8D",
            "unit_ID":"84F212893A8B45BC8A8CB055499D7260",
            "outer_pack_size":0,
            "category_ID":"EB169E94305F41E0BE0B32C426BC7BBB",
            "ABC_category":"",
            "warning_quantity":0,
            "user_field_5":0,
            "print_units_in_dis_labels":false,
            "volume_per_outer_pack":0,
            "normal_stock":false,
            "critical_stock":false,
            "spare_non_stock":false,
            "non_stock_name_ID":"",
            "is_sync":false,
            "sms_code":"",
            "category2_ID":"",
            "category3_ID":"",
            "buy_price":0,
            "VEN_category":"V",
            "universalcodes_code":"",
            "universalcodes_name":"",
            "kit_data":null,
            "custom_data":null,
            "Link_182":{
               "__KEY":""
            },
            "Link_146":{
               "__KEY":""
            },
            "Link_177":{
               "__KEY":"EB169E94305F41E0BE0B32C426BC7BBB"
            },
            "Link_241":{
               "__KEY":"84F212893A8B45BC8A8CB055499D7260"
            },
            "Link_180":{
               "__KEY":""
            },
            "Link_181":{
               "__KEY":""
            }
         },
         "requisition":{
            "__KEY":"80AC28F337804413B29B0832B0621047"
         },
         "Link_271":{
            "__KEY":""
         },
         "initialStockOnHand":0,
         "incomingStock":0,
         "outgoingStock":0,
         "inventoryAdjustments":0
      },
      {
         "ID":"96564CC32A274B7DA6B04B13A079B107",
         "requisition_ID":"80AC28F337804413B29B0832B0621047",
         "item_ID":"DE38AFB9500548E28FE05CBF5CD3B819",
         "stock_on_hand":70,
         "actualQuan":0,
         "imprest_or_prev_quantity":0,
         "colour":-255,
         "line_number":2,
         "Cust_prev_stock_balance":0,
         "Cust_stock_received":0,
         "Cust_stock_order":0,
         "comment":"",
         "Cust_loss_adjust":0,
         "days_out_or_new_demand":0,
         "previous_stock_on_hand":0,
         "daily_usage":0,
         "suggested_quantity":0,
         "adjusted_consumption":0,
         "linked_requisition_line_ID":"",
         "purchase_order_line_ID":"",
         "item":{
            "ID":"DE38AFB9500548E28FE05CBF5CD3B819",
            "item_name":"Salbutamol Inhaler",
            "start_of_year_date":"0000-00-00T00:00:00.000Z",
            "manufacture_method":"",
            "default_pack_size":1,
            "dose_picture":"[object Picture]",
            "atc_category":"",
            "medication_purpose":"",
            "instructions":"",
            "user_field_7":false,
            "flags":"",
            "ddd_value":"",
            "code":"AR07102",
            "other_names":"",
            "type_of":"general",
            "price_editable":false,
            "margin":0,
            "barcode_spare":"33",
            "spare_ignore_for_orders":false,
            "sms_pack_size":0,
            "expiry_date_mandatory":false,
            "volume_per_pack":0,
            "department_ID":"",
            "weight":1,
            "essential_drug_list":false,
            "catalogue_code":"",
            "indic_price":0,
            "user_field_1":"",
            "spare_hold_for_issue":false,
            "builds_only":false,
            "reference_bom_quantity":0,
            "use_bill_of_materials":false,
            "description":"",
            "spare_hold_for_receive":false,
            "Message":"",
            "interaction_group_ID":"",
            "spare_pack_to_one_on_receive":false,
            "cross_ref_item_ID":"",
            "spare_shelf_location_bulk":"",
            "user_field_4":false,
            "user_field_6":"",
            "spare_internal_analysis":0,
            "user_field_2":"",
            "user_field_3":"",
            "ddd factor":0,
            "account_stock_ID":"52923505A91447B9923BA34A4F332014",
            "account_purchases_ID":"330ACC81721C4126BD5DD6769466C5C4",
            "account_income_ID":"EF34ADD07C014AB8914E30CA2E3FEA8D",
            "unit_ID":"",
            "outer_pack_size":0,
            "category_ID":"",
            "ABC_category":"",
            "warning_quantity":0,
            "user_field_5":0,
            "print_units_in_dis_labels":false,
            "volume_per_outer_pack":0,
            "normal_stock":false,
            "critical_stock":false,
            "spare_non_stock":false,
            "non_stock_name_ID":"",
            "is_sync":false,
            "sms_code":"",
            "category2_ID":"",
            "category3_ID":"",
            "buy_price":0,
            "VEN_category":"",
            "universalcodes_code":"",
            "universalcodes_name":"",
            "kit_data":null,
            "custom_data":null,
            "Link_182":{
               "__KEY":""
            },
            "Link_146":{
               "__KEY":""
            },
            "Link_177":{
               "__KEY":""
            },
            "Link_241":{
               "__KEY":""
            },
            "Link_180":{
               "__KEY":""
            },
            "Link_181":{
               "__KEY":""
            }
         },
         "requisition":{
            "__KEY":"80AC28F337804413B29B0832B0621047"
         },
         "Link_271":{
            "__KEY":""
         },
         "initialStockOnHand":0,
         "incomingStock":0,
         "outgoingStock":0,
         "inventoryAdjustments":0
      },
      {
         "ID":"ED71A10C100645C9AEFCC7B00CC11B9C",
         "requisition_ID":"80AC28F337804413B29B0832B0621047",
         "item_ID":"F80FE2C6123C4B78813D13C0DECB6542",
         "stock_on_hand":1100000,
         "actualQuan":0,
         "imprest_or_prev_quantity":0,
         "colour":-255,
         "line_number":3,
         "Cust_prev_stock_balance":0,
         "Cust_stock_received":0,
         "Cust_stock_order":0,
         "comment":"",
         "Cust_loss_adjust":0,
         "days_out_or_new_demand":0,
         "previous_stock_on_hand":0,
         "daily_usage":0,
         "suggested_quantity":0,
         "adjusted_consumption":0,
         "linked_requisition_line_ID":"",
         "purchase_order_line_ID":"",
         "item":{
            "ID":"F80FE2C6123C4B78813D13C0DECB6542",
            "item_name":"Zinc Sulphate Dispersable 20mg tabs",
            "start_of_year_date":"0000-00-00T00:00:00.000Z",
            "manufacture_method":"",
            "default_pack_size":100,
            "dose_picture":"[object Picture]",
            "atc_category":"MEDICINES USED IN DIARRHOEA",
            "medication_purpose":"",
            "instructions":"",
            "user_field_7":false,
            "flags":"",
            "ddd_value":"600MG",
            "code":"AR07101",
            "other_names":"",
            "type_of":"general",
            "price_editable":false,
            "margin":0,
            "barcode_spare":"30",
            "spare_ignore_for_orders":false,
            "sms_pack_size":0,
            "expiry_date_mandatory":false,
            "volume_per_pack":0,
            "department_ID":"",
            "weight":0,
            "essential_drug_list":true,
            "catalogue_code":"",
            "indic_price":0,
            "user_field_1":"",
            "spare_hold_for_issue":false,
            "builds_only":false,
            "reference_bom_quantity":0,
            "use_bill_of_materials":false,
            "description":"",
            "spare_hold_for_receive":false,
            "Message":"",
            "interaction_group_ID":"",
            "spare_pack_to_one_on_receive":false,
            "cross_ref_item_ID":"",
            "spare_shelf_location_bulk":"",
            "user_field_4":true,
            "user_field_6":"",
            "spare_internal_analysis":0,
            "user_field_2":"",
            "user_field_3":"",
            "ddd factor":30,
            "account_stock_ID":"52923505A91447B9923BA34A4F332014",
            "account_purchases_ID":"330ACC81721C4126BD5DD6769466C5C4",
            "account_income_ID":"EF34ADD07C014AB8914E30CA2E3FEA8D",
            "unit_ID":"84F212893A8B45BC8A8CB055499D7260",
            "outer_pack_size":0,
            "category_ID":"B4A0CB55544B4473B257CC8A8A433CD8",
            "ABC_category":"",
            "warning_quantity":0,
            "user_field_5":0,
            "print_units_in_dis_labels":false,
            "volume_per_outer_pack":0,
            "normal_stock":false,
            "critical_stock":true,
            "spare_non_stock":false,
            "non_stock_name_ID":"",
            "is_sync":false,
            "sms_code":"",
            "category2_ID":"",
            "category3_ID":"",
            "buy_price":0,
            "VEN_category":"",
            "universalcodes_code":"",
            "universalcodes_name":"",
            "kit_data":null,
            "custom_data":null,
            "Link_182":{
               "__KEY":""
            },
            "Link_146":{
               "__KEY":""
            },
            "Link_177":{
               "__KEY":"B4A0CB55544B4473B257CC8A8A433CD8"
            },
            "Link_241":{
               "__KEY":"84F212893A8B45BC8A8CB055499D7260"
            },
            "Link_180":{
               "__KEY":""
            },
            "Link_181":{
               "__KEY":""
            }
         },
         "requisition":{
            "__KEY":"80AC28F337804413B29B0832B0621047"
         },
         "Link_271":{
            "__KEY":""
         },
         "initialStockOnHand":0,
         "incomingStock":0,
         "outgoingStock":0,
         "inventoryAdjustments":0
      }
   ]
}

Have also confirmed the fields which should be altered.

eSIGL Field = mSupply Fields

  • stockInHand = (beginningBalance - actualQuan) + Cust_stock_receieved + Cust_loss_adjust
  • quantityReceived = Cust_stock_received
  • quantityDispensed = actualQuan
  • totalLossesAndAdjustments = Cust_loss_adjust
  • quantityRequested = Cust_stock_order

Refacgtor integrate requisiton function

Large function which needs refactoring, may be difficult because of all the throws etc to come to a more concise, nice function. May also require refctoring and changing return values of other functions so that composing is easier

Explanation docs

Docs will need to be written explaining the process a requisition will take. Including all confusing and ambiguous features for Mark.

GET periods

Method for retrieving an array of periods from eSigl.

Error conditions:

  • 500: Server error.
  • 401: Unauthorized.
  • Response object field rnrlist is not NULL (Indicating there is a waiting requisition to be authorized)
  • periods array length is 0.

error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be an array of periods.

POST Convert requisition to an order

Method for converting a requisition to an order in the eSigl system given a requisitionId.

NOTE: On catching an error, this method must attempt to delete the corresponding requisition before exiting.

error conditions:

  • 500: Server error
  • 401: Unauthorized.

error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be true on success.

Periods matching method

Method for matching a time given in the input parameters with a period retrieved from eSigl.

Error conditions:

  • No matching period
  • There exists a period earlier than the date provided.

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be the matched periods ID.

fullSupplyLineItems with Skipped: true

The eLMIS server will send an array of fullSupplyLineItems which need to be modified in order to submit a requisition.

Some of these fullSupplyLineItems have a field skipped. If this is set to true, these items can be skipped. Currently the requisition merging function will error on receiving any difference in the number of full supply line items. If the eSIGL server sends extra items with skipped: true, these requisitions will not successfully be pushed

Rewrite of periods function

We are now using a defined start and end date for periods. Periods currently uses just a start date which has to be somewhere within the period.

We need a new periods function which will validate on only start and end dates matching.

Possibly keep the current period function as it may be used in the future if matching both start and end dates is to costly.

Requisition Match

Method for mapping input requisition and requisitionLine fields to a the equivalent eSigl fields.

Any fullSupplyLineItem (eSigl term for requisitionLine) which has no matching requisitionLine provided as input will need to have their previousStockOnHand and stockOnHand fields set to equal while all other appropriate fields are set to 0.

Note: This may need to be split into multiple methods - first to check fields, then to do the mapping(?). Also, if an error is thrown we must try to delete the requisition before exiting.

Error conditions:

  • A requisition Item does not match a field in the eSigl program (Opposite of situation described above. 4D is trying to add an item which is not in the program which is an error)
  • A regime item does not match a field in the eSigl program (Same as above)

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be an object ready to be validated and saved into eSigl.

parameter validation

The parameter validation function is out dated using an assumption about input that is no longer valid.

Input will be an object in the form (at minimum to check for):

{
requisition: {
        store: {},
        requisitionLines: [],
        period: ""
    }
options: {
        baseURL: "",
    }
}

Enhanced errors for differing status codes in requests

Currently each request is catching a 401 and 500 at minimum. Each endpoint has seemingly vastly different status code responses for differing requests.

EG a request to submit a requisition which already has the status SUBMITTED receives a 400 status code in response.

It would be good to enhance each request such that specific error codes can be captured and translated in the thrown errorObject. Translating a request to /submit.json with a response status code of 400 to Requisition has already been submitted.

POST Requisition (creation)

Method for creating a requisition within eSigl using the retrieved facilityId, programId, periodId and requisition type (emergency etc.) from the input parameters.

Error conditions:

  • 401: Unauthorized.
  • 500: Server error (This is will indicate a periodId, facilityId or programId is incorrect - no way to determine which one(?))

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value is a requisitionObject (rnr)

GET facilities method

Method for retrieving an array of facilities from eSigl.

Error conditions:

  • 401: Unauthorized.
  • 500: Server error.
  • facilities array length = 0.

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be an array of facilities.

Testing script

Will need scripts to be made in 4D which will create requisitions(?) with different variations and use these requisitions to try to push to eSIGL.

Will attempt to login, get programs, facilities etc. as well as create a requisition, submit, delete etcetc.

This can most likely be done with the same 4D requisition as long as it is deleted throughout the process.

POST Authorize requisition

Method for posting an authorize request for a given requisitionId

NOTE: On an error, this method must attempt to delete the given requisitionId before exiting.

Error conditions:

  • 500: Server error.
  • 401: Unauthorized

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be true on success.

Facilities URL Incorrect

Currently the facilities function is using the endpoint /users/facilities.json. This endpoint seems to return an empty list for any user.

To fix this, there is a different endpoint which can be used: /create/requisition/supervised/{programId}/facilities.json which will return all the supervising facilities for a given program.

Initial check method

Method for initial checking of input parameters:

Checks:

  • numbers of parameters (1 - incoming object to integrate)
  • existence of certain fields ( requisition, requisitionLines) within the object
  • types of the fields ( requisition: Object, requisitionLines: Array)

Throws an error in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be true on success.

error objects

Error objects are a bit messy. Need to determine if more "constants" should be used or something similar to reduce the code within each function.

POST Submit requisition

Method to submit a requisition into the eSigl system.

NOTE: At this point the requisition will be validated by eSigl. If this is not successful, we need to delete the created requisition before finishing.

Error conditions:

  • 500: Server error: This will be the indication of a malformed requisition, no details will be provided on exactly what the problem is.
  • 401: Unauthorized.

Error response should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be true on success.

Doc strings

Need to clean up more or less all doc strings. Need to properly document parameters, in particular for objects. Were written a while ago so re-reading should give a different perspective on their clarity.

Create requisition function return value

The requisition creation function currently returns the ID of the created requisition. It would be easier for this function to return the fully constructed requisition. This makes the merging of a 4D and eSIGL requisition a lot easier.

Create testing setup

Need to create a testing set up which will enable pushing requisitions from mSupply to eSIGL.

Will need:

  • eSIGL Facility and program with 3 items.
  • A schedule with defined periods, matching budgeting_periods in mSupply.
  • mSupply store and program codes to match the eSIGL facility and program codes.
  • mSupply item codes to match eSIGL item codes.

Devops: Initial setup

Set up an initial project with:

  • ESLint: Ensuring it is consistent with other mSupply projects.
  • Prettier: Ensuring it is consistent with other mSupply projects.
  • Babel: Ensuring all code up to ES8 is transpiled to enable the use of async/await and importing.
  • Husky: Ensuring a pre-commit hook to run ESLint over code before commiting

GET Programs method

Method to retrieve an array of programs associated with the user.

Error conditions:

  • 401: Unauthorized.
  • 500: Server error.
  • Programs array length = 0 - If no programs exist, something has gone wrong.

Should throw an error in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

return value should be an array of programs retrieved.

Custom Errors

Create a system for custom errors.

Potentially custom Error objects, or simply Objects with predefined error and errorCode fields.

More discussion to be had.

Facilities matching method

Method for matching the facility code from input parameters to a facility within the array of facilities retrieved from eSgil.

Error conditions:

  • No matching facility

Error should be in the form:

{
   success: false,
   error: ' .. ',
    errorCode: ' ... ',
}

Return value should be true on a match.

Order to requisition conversion function - return value

The return value of the requisition conversion function is incorrect. The response from the server is empty, not a an empty JSON object: {}.

The response code on a successful conversion is also 201 - it seems accurate to have all other status codes throw errors.

Integrate errors return value and error catching

The integrate return value for errors is incomplete, as a JS run time error will be in a different format as other types. This will need to be wrapped with an error code, as well as the deleted status of the requisition, if it has been created.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.