diff --git a/modules/field/commerce_cost_field.libraries.yml b/modules/field/commerce_cost_field.libraries.yml
new file mode 100644
index 0000000..a8dcb67
--- /dev/null
+++ b/modules/field/commerce_cost_field.libraries.yml
@@ -0,0 +1,7 @@
+sale_price:
+  version: 1.x
+  js:
+    js/sale_price_calculation.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupalSettings
diff --git a/modules/field/config/schema/commerce_cost_field.schema.yml b/modules/field/config/schema/commerce_cost_field.schema.yml
new file mode 100644
index 0000000..7b22de5
--- /dev/null
+++ b/modules/field/config/schema/commerce_cost_field.schema.yml
@@ -0,0 +1,10 @@
+field.widget.settings.commerce_price_with_cost:
+  type: mapping
+  label: 'Field selection'
+  mapping:
+    price_field:
+      type: string
+      label: 'Commerce price field'
+    cost_field:
+      type: string
+      label: 'Commerce cost field'
diff --git a/modules/field/js/sale_price_calculation.js b/modules/field/js/sale_price_calculation.js
new file mode 100644
index 0000000..c68597b
--- /dev/null
+++ b/modules/field/js/sale_price_calculation.js
@@ -0,0 +1,71 @@
+(function ($, Drupal) {
+  'use strict';
+
+  /**
+   * @file
+   * Defines sale price based off product price, cost and markup.
+   */
+
+  Drupal.behaviors.commerce_cost_calculation = {
+    attach: function (context, settings) {
+      var markupClass = 'field--name-field-markup-percentage';
+      var priceClass = '.field--name-' + drupalSettings.commerce_cost_field.price_field;
+      var costClass = '.field--name-' + drupalSettings.commerce_cost_field.cost_field;
+
+      // Commerce price DOM elements.
+      var $markup = '';
+      var $price = $(priceClass).find('input');
+      var $cost = $(costClass).find('input');
+
+      // The markup textfield.
+      var markupElement = '<label for="markup-percentage" class="markup-field-label">Markup percentage</label>';
+      markupElement += '<input type="text" size="10" id="markup-percentage" class="form-text ' + markupClass + '">';
+      markupElement += '<span class="field-suffix">%</span>';
+      $markup = $(markupElement);
+      if ($('#markup-percentage').length === 0) {
+        $markup.insertAfter($(costClass));
+      }
+      markupClass = '.' + markupClass;
+      $markup = $(markupClass);
+
+      // Cost and Markup fields changed - set price.
+      $cost.add($markup).on('keyup change', function() {
+        if ($cost.val() !== '' && $markup.val() !== '') {
+          var priceNumber = $price.get(0);
+          var value = $cost.val() * (1 + $markup.val() / 100);
+          value = value.toFixed(2);
+
+          if (!isNaN(value)) {
+            $(priceNumber)
+              .val(value)
+              .css('background-color', '#f0ff00');
+
+            setTimeout(function(){
+              $(priceNumber).css('background-color', '#fcfcfa');
+            }, 500);
+          }
+        }
+      });
+
+      // Price field changed - set markup.
+      $price.on('keyup change', function() {
+        if ($price.val() !== '' && $cost.val() !== '') {
+          var value = (($price.val() - $cost.val()) / $cost.val()) * 100;
+          value = value.toFixed(2);
+
+          if (!isNaN(value)) {
+            $markup
+              .val(value)
+              .css('background-color', '#f0ff00');
+
+            setTimeout(function(){
+              $markup.css('background-color', '#fcfcfa');
+            }, 500);
+          }
+        }
+      });
+
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/modules/field/src/Plugin/Field/FieldWidget/PriceWithCostWidget.php b/modules/field/src/Plugin/Field/FieldWidget/PriceWithCostWidget.php
new file mode 100644
index 0000000..885696e
--- /dev/null
+++ b/modules/field/src/Plugin/Field/FieldWidget/PriceWithCostWidget.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Drupal\commerce_cost_field\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Plugin implementation of the 'commerce_price_with_cost' widget.
+ *
+ * @FieldWidget(
+ *   id = "commerce_price_with_cost",
+ *   label = @Translation("Price with Cost"),
+ *   field_types = {
+ *     "commerce_price"
+ *   }
+ * )
+ */
+class PriceWithCostWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'price_field' => '',
+      'cost_field' => '',
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+
+    $options = [];
+    $entity_type = $this->fieldDefinition->getTargetEntityTypeId();
+    $bundle = $this->fieldDefinition->getTargetBundle();
+    if (empty($bundle)) {
+      return $options;
+    }
+
+    $fields = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type, $bundle);
+    /** @var \Drupal\field\Entity\FieldConfig $field */
+    foreach ($fields as $field) {
+      if ($field->getType() === 'commerce_price') {
+        $options[$field->getName()] = $field->getLabel() . ' (' . $field->getName() . ')';
+      }
+    }
+
+    $form['price_field'] = [
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => $this->t('Select Commerce price field'),
+      '#default_value' => $options,
+    ];
+    $form['cost_field'] = [
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => $this->t('Select Cost price field'),
+      '#default_value' => $this->getSetting('cost_field'),
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $element['#type'] = 'commerce_price';
+    $element['#available_currencies'] = array_filter($this->getFieldSetting('available_currencies'));
+
+    // Attach the library.
+    $form['#attached']['library'][] = 'commerce_cost_field/sale_price';
+    $form['#attached']['drupalSettings']['commerce_cost_field'] = [
+      'price_field' => str_replace('_', '-', $this->settings['price_field']),
+      'cost_field' => str_replace('_', '-', $this->settings['cost_field']),
+    ];
+
+    if (!$items[$delta]->isEmpty()) {
+      $element['#default_value'] = $items[$delta]->toPrice()->toArray();
+    }
+
+//    \Drupal::logger('abcd')->notice('<pre>' . print_r($element, TRUE) . '</pre>');
+
+    return $element;
+  }
+
+}
diff --git a/src/OrderProcessor/ApplyCost.php b/src/OrderProcessor/ApplyCost.php
index ccbf623..c63958a 100644
--- a/src/OrderProcessor/ApplyCost.php
+++ b/src/OrderProcessor/ApplyCost.php
@@ -38,7 +38,9 @@ class ApplyCost implements OrderProcessorInterface {
     $context = new Context($order->getCustomer(), $order->getStore());
     foreach ($order->getItems() as $orderItem) {
       $cost = $this->chainCostResolver->resolve($orderItem->getPurchasedEntity(), $orderItem->getQuantity(), $context);
-      $orderItem->set('field_cost', $cost);
+      if ($orderItem->hasField('field_cost')) {
+        $orderItem->set('field_cost', $cost);
+      }
     }
   }
 
