From a4b8cb7008c02db9727e2b8b59188faf3038eb2b Mon Sep 17 00:00:00 2001 From: boudet jean pascal <68547382+atm-jpb@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:42:31 +0100 Subject: [PATCH] NEW : adds visual indicators on the Sales Order card (commande/card.php) (#37460) * This PR adds visual indicators on the Sales Order card (commande/card.php) to quickly identify if an order or its lines are shippable based on current stock levels. This feature mirrors the existing functionality found in the Orders List, bringing valuable logistics information directly into the Order Card context. Key Features: Global Shippable Status: Adds a "shippable" icon (Truck) next to the "Planned delivery date" field. Logic: Checks if all products in the order are in stock. Condition: Visible only if Stock and Shipment modules are enabled, a delivery date is set, and the order is validated. Visual: Green icon if fully shippable, Red/Warning if stock is insufficient. Includes a detailed tooltip. Per-Line Shippable Status: Adds a new "Shippable" column in the product lines table. Logic: Compares real stock vs. remaining quantity to ship for each line. Visual: Displays a green/red status bullet (standard Dolibarr status icons) directly in the line. Implementation: Done by updating objectline_title.tpl.php and objectline_view.tpl.php with specific checks for the commande element. New Configuration Option: Added a hidden option ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD to disable this feature if needed (configurable in Home > Setup > Other Setup or via module settings). Backend Optimization: Added a new method getShippableInfos() in commande.class.php to centralize the stock check logic (optimized with stock caching to avoid N+1 query issues). Technical Details: Modified Files: commande/card.php: Integration of the global icon next to the date. commande/class/commande.class.php: Added getShippableInfos() method. core/tpl/objectline_title.tpl.php: Added "Shippable" column header (conditional for Orders). core/tpl/objectline_view.tpl.php: Added "Shippable" column cell content (conditional for Orders). Performance: Logic uses static caching for product stock to minimize database impact when rendering large orders. * missed element * img_picto * phan add * load_stock and global $i * phan * ci retour * change icon change phan directive * phan * Fight against optionflation Signed-off-by: Laurent Destailleur * Change condition for displaying shippable icon Signed-off-by: Laurent Destailleur * Change condition for displaying shippable status icon Signed-off-by: Laurent Destailleur * Update card.php Signed-off-by: Laurent Destailleur * Update shippable status condition in template Signed-off-by: Laurent Destailleur * Update shippable status condition logic Signed-off-by: Laurent Destailleur --------- Signed-off-by: Laurent Destailleur Co-authored-by: jpb Co-authored-by: Laurent Destailleur --- htdocs/commande/card.php | 14 ++ htdocs/commande/class/commande.class.php | 160 +++++++++++++++++++++++ htdocs/commande/list.php | 112 ++-------------- htdocs/core/tpl/objectline_edit.tpl.php | 14 +- htdocs/core/tpl/objectline_title.tpl.php | 5 + htdocs/core/tpl/objectline_view.tpl.php | 35 ++++- htdocs/langs/en_US/admin.lang | 1 + htdocs/langs/en_US/main.lang | 2 + 8 files changed, 240 insertions(+), 103 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 5eb1ccc9a57..422f38d5ae7 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -3117,6 +3117,20 @@ if ($action == 'create' && $usercancreate) { print ' ' . img_picto($langs->trans("Late") . ' : ' . $object->showDelay(), "warning"); } } + // --- SHIPPABLE icon --- + if (isModEnabled('stock') && isModEnabled('shipping') && !getDolGlobalString('ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD') && !empty($object->delivery_date)) { + $shippableInfos = $object->getShippableInfos(); + + if (!empty($shippableInfos['has_product'])) { + print ' '; + print $form->textwithtooltip('', $shippableInfos['textinfo'], 2, 1, $shippableInfos['texticon'], '', 2); + + if (!empty($shippableInfos['warning'])) { + print ' '; + print $form->textwithtooltip('', $langs->trans("NotEnoughForAllOrders"), 2, 1, img_picto('', 'error', '', 0, 0, 0, '', '2'), '', 2); + } + } + } print ''; print ''; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 2436944576d..5760dc26048 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -4320,4 +4320,164 @@ class Commande extends CommonOrder { return $this->setSignedStatusCommon($user, $status, $notrigger, $triggercode); } + + /** + * Compute shippable status and tooltip/icon for the order. + * + * @param array $options Extra options (reserved for future use) + * @return array Array with keys: has_product, shippable, texticon, textinfo, warning + * / + */ + public function getShippableInfos(array $options = array()) : array + { + global $conf, $langs; + + $langs->loadLangs(array('orders', 'sendings', 'stocks', 'products')); + + $result = array( + 'has_product' => false, + 'shippable' => false, + 'texticon' => '', + 'textinfo' => '', + 'warning' => false, + ); + + // Requested naming for statuses + if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_CLOSED) { + return $result; + } + + + $genericCommande = $this; + $genericProduct = new Product($this->db); + + + $productstatcache = array(); + $productstatcachevirtual = array(); + + + $genericCommande->getLinesArray(); // Load array ->lines + $genericCommande->loadExpeditions(); // Load array ->expeditions + + $notshippable = 0; + $has_reliquat = 0; + $warning = 0; + $textinfo = ''; + $textwarning = ''; + $nbprod = 0; + + $genericProduct = new Product($this->db); + + $numlines = count($genericCommande->lines); + for ($lig = 0; $lig < $numlines; $lig++) { + $orderLine = $genericCommande->lines[$lig]; // @phan-var-force OrderLine $orderLine + + if (isset($genericCommande->expeditions[$orderLine->id])) { + $reliquat = $orderLine->qty - $genericCommande->expeditions[$orderLine->id]; + } else { + $reliquat = $orderLine->qty; + } + + if ($orderLine->product_type == 0 && $orderLine->fk_product > 0) { // product, not service + $nbprod = 1; + + if (empty($productstatcache[$orderLine->fk_product])) { + $genericProduct->fetch($orderLine->fk_product); + $genericProduct->load_stock('nobatch,warehouseopen'); // loadvirtualstock included + + $productstatcache[$orderLine->fk_product]['stockreel'] = $genericProduct->stock_reel; + $productstatcachevirtual[$orderLine->fk_product]['stockreel'] = $genericProduct->stock_theorique; + } + + $genericProduct->stock_reel = $productstatcache[$orderLine->fk_product]['stockreel']; + $genericProduct->stock_theorique = $productstatcachevirtual[$orderLine->fk_product]['stockreel']; + + if ($reliquat > 0) { + $has_reliquat = 1; + if (!getDolGlobalString('SHIPPABLE_ORDER_ICON_IN_LIST')) { + $textinfo .= $reliquat . ' x ' . $orderLine->product_ref . ' ' . dol_trunc($orderLine->product_label, 20); + $textinfo .= ' - ' . $langs->trans("Stock") . ': ' . $genericProduct->stock_reel . ''; + $textinfo .= ' - ' . $langs->trans("VirtualStock") . ': ' . $genericProduct->stock_theorique . ''; + if ($reliquat != $orderLine->qty) { + $textinfo .= ' ' . $langs->trans("QtyInOtherShipments") . ' ' . ($orderLine->qty - $reliquat) . ''; + } + $textinfo .= '
'; + } else { + // BUGGED CODE (kept for backward compatibility and hidden conf) + $stockorder = 0; + $stockordersupplier = 0; + + if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT') || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')) { + if (isModEnabled('order')) { + if (empty($productstatcache[$orderLine->fk_product]['statsordercustomer'])) { + $genericProduct->fetch($orderLine->fk_product); + $genericProduct->load_stats_commande(0, '1,2'); + $productstatcache[$orderLine->fk_product]['statsordercustomer'] = $genericProduct->stats_commande['qty']; + } + $genericProduct->stats_commande['qty'] = $productstatcache[$orderLine->fk_product]['statsordercustomer']; + $stockorder = $genericProduct->stats_commande['qty']; + + if (isModEnabled('supplier_order')) { + if (empty($productstatcache[$orderLine->fk_product]['statsordersupplier'])) { + $genericProduct->load_stats_commande_fournisseur(0, '3'); + $productstatcache[$orderLine->fk_product]['statsordersupplier'] = $genericProduct->stats_commande_fournisseur['qty']; + } + $genericProduct->stats_commande_fournisseur['qty'] = $productstatcache[$orderLine->fk_product]['statsordersupplier']; + $stockordersupplier = $genericProduct->stats_commande_fournisseur['qty']; + } + } + } + + $textinfo .= $reliquat . ' x ' . $orderLine->ref . ' ' . dol_trunc($orderLine->product_label, 20); + $textinfo .= ' ' . $langs->trans("Available") . '  ' . $genericProduct->stock_reel . '..' . $stockorder; + + if ($stockorder && $genericProduct->stock_reel < ($genericProduct->stock_reel - $stockorder + $reliquat)) { + $warning++; + $textwarning .= '' . $langs->trans("Available") . '  ' . $genericProduct->stock_reel . '..' . $stockorder . ''; + } else { + if ($reliquat > $genericProduct->stock_reel) { + $textinfo .= ' ' . $langs->trans("Available") . '  ' . $genericProduct->stock_reel . ''; + } else { + $textinfo .= ' ' . $langs->trans("Available") . '  ' . $genericProduct->stock_reel . ''; + } + } + + if (isModEnabled('supplier_order')) { + $textinfo .= ' ' . $langs->trans("SupplierOrder") . '  ' . $stockordersupplier; + } + if ($reliquat != $orderLine->qty) { + $textinfo .= ' ' . $langs->trans("QtyInOtherShipments") . ' ' . ($orderLine->qty - $reliquat) . ''; + } + $textinfo .= '
'; + } + + if ($reliquat > $genericProduct->stock_reel) { + $notshippable++; + } + } + } + } + + if ($nbprod) { + if (!$has_reliquat) { + $texticon = img_picto('', 'statut5', '', 0, 0, 0, '', 'paddingleft'); + $textinfo = $texticon . ' ' . $langs->trans("Shipped"); + $result['shippable'] = true; + } elseif ($notshippable) { + $texticon = img_picto('', 'dolly', '', 0, 0, 0, '', 'error paddingleft'); + $textinfo = $texticon . ' ' . $langs->trans("NonShippable") . '
' . $textinfo; + $result['shippable'] = false; + } else { + $texticon = img_picto('', 'dolly', '', 0, 0, 0, '', 'green paddingleft'); + $textinfo = $texticon . ' ' . $langs->trans("Shippable") . '
' . $textinfo; + $result['shippable'] = true; + } + $result['has_product'] = true; + $result['texticon'] = $texticon; + $result['textinfo'] = $textinfo; + $result['warning'] = !empty($warning); + } + + return $result; + } } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 632706cbfe6..b86c4406119 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -2999,108 +2999,22 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['shippable']['checked'])) { print ''; if (!empty($show_shippable_command) && isModEnabled('stock')) { - $text_icon = ''; - if (($obj->fk_statut > $generic_commande::STATUS_DRAFT) && ($obj->fk_statut < $generic_commande::STATUS_CLOSED)) { - $generic_commande->getLinesArray(); // Load array ->lines - $generic_commande->loadExpeditions(); // Load array ->expeditions + $commande = new Commande($db); + $commande->id = (int) $obj->rowid; + $commande->status = (int) $obj->fk_statut; + $commande->statut = (int) $obj->fk_statut; - $numlines = count($generic_commande->lines); // Loop on each line of order - for ($lig = 0; $lig < $numlines; $lig++) { - $orderLine = $generic_commande->lines[$lig]; - '@phan-var-force OrderLine $orderLine'; - if (isset($generic_commande->expeditions[$orderLine->id])) { - $reliquat = $orderLine->qty - $generic_commande->expeditions[$orderLine->id]; - } else { - $reliquat = $orderLine->qty; - } - if ($orderLine->product_type == 0 && $orderLine->fk_product > 0) { // If line is a product and not a service - $nbprod++; // order contains real products - $generic_product->id = $orderLine->fk_product; + $shippableInfos = $commande->getShippableInfos(); - // Get local and virtual stock and store it into cache - if (empty($productstat_cache[$orderLine->fk_product])) { - $generic_product->load_stock('nobatch,warehouseopen'); // ->load_virtual_stock() is already included into load_stock() - $productstat_cache[$orderLine->fk_product]['stock_reel'] = $generic_product->stock_reel; - $productstat_cachevirtual[$orderLine->fk_product]['stock_reel'] = $generic_product->stock_theorique; - } else { - $generic_product->stock_reel = $productstat_cache[$orderLine->fk_product]['stock_reel']; - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $generic_product->stock_theorique = $productstat_cachevirtual[$orderLine->fk_product]['stock_reel']; - } - - if ($reliquat > $generic_product->stock_reel) { - $notshippable++; - } - if (!getDolGlobalString('SHIPPABLE_ORDER_ICON_IN_LIST')) { // Default code. Default should be this case. - $text_info .= $reliquat.' x '.$orderLine->product_ref.' '.dol_trunc($orderLine->product_label, 20); - $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel.''; - $text_info .= ' - '.$langs->trans("VirtualStock").': '.$generic_product->stock_theorique.''; - $text_info .= ($reliquat != $orderLine->qty ? ' ('.$langs->trans("QtyInOtherShipments").' '.($orderLine->qty - $reliquat).')' : ''); - $text_info .= '
'; - } else { // BUGGED CODE. - // DOES NOT TAKE INTO ACCOUNT MANUFACTURING. THIS CODE SHOULD BE USELESS. PREVIOUS CODE SEEMS COMPLETE. - // COUNT STOCK WHEN WE SHOULD ALREADY HAVE VALUE - // Detailed virtual stock, looks bugged, incomplete and need heavy load. - // stock order and stock order_supplier - $stock_order = 0; - $stock_order_supplier = 0; - if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT') || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')) { // What about other options ? - if (isModEnabled('order')) { - if (empty($productstat_cache[$orderLine->fk_product]['stats_order_customer'])) { - $generic_product->load_stats_commande(0, '1,2'); - $productstat_cache[$orderLine->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; - } else { - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $generic_product->stats_commande['qty'] = $productstat_cache[$orderLine->fk_product]['stats_order_customer']; - } - $stock_order = $generic_product->stats_commande['qty']; - } - if (isModEnabled("supplier_order")) { - if (empty($productstat_cache[$orderLine->fk_product]['stats_order_supplier'])) { - $generic_product->load_stats_commande_fournisseur(0, '3'); - $productstat_cache[$orderLine->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; - } else { - // @phan-suppress-next-line PhanTypeInvalidDimOffset - $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$orderLine->fk_product]['stats_order_supplier']; - } - $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; - } - } - $text_info .= $reliquat.' x '.$orderLine->ref.' '.dol_trunc($orderLine->product_label, 20); - $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; - if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $orderLine->qty)) { - $warning++; - $text_warning .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; - } - if ($reliquat > $generic_product->stock_reel) { - $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; - } else { - $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; - } - if (isModEnabled("supplier_order")) { - $text_info .= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier; - } - $text_info .= ($reliquat != $orderLine->qty ? ' ('.$langs->trans("QtyInOtherShipments").' '.($orderLine->qty - $reliquat).')' : ''); - $text_info .= '
'; - } - } - } - if ($notshippable == 0) { - $text_icon = img_picto('', 'dolly', '', 0, 0, 0, '', 'green paddingleft'); - $text_info = $text_icon.' '.$langs->trans('Shippable').'
'.$text_info; - } else { - $text_icon = img_picto('', 'dolly', '', 0, 0, 0, '', 'error paddingleft'); - $text_info = $text_icon.' '.$langs->trans('NonShippable').'
'.$text_info; - } - } - - if ($nbprod) { // If there is at least one product to ship, we show the shippable icon - print ''; - print $form->textwithtooltip('', $text_info, 2, 1, $text_icon, '', 2); + if ($shippableInfos['has_product']) { + print ''; + print $form->textwithtooltip('', $shippableInfos['textinfo'], 2, 1, $shippableInfos['texticon'], '', 2); print ''; - } - if ($warning) { // Always false in default mode - print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'
'.$text_warning, 2, 1, img_picto('', 'error'), '', 2); + + if (!empty($shippableInfos['warning'])) { + // On ne remonte plus le détail textwarning, mais on garde l’icône d’avertissement + print $form->textwithtooltip('', $langs->trans("NotEnoughForAllOrders"), 2, 1, img_picto('', 'error', '', 0, 0, 0, '', '2'), '', 2); + } } } print ''; diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 2291df4273f..5ba85d81bfe 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -58,7 +58,6 @@ if (empty($object) || !is_object($object)) { print "Error, template page can't be called as URL"; exit(1); } - ' @phan-var-force Propal|Contrat|Commande|Facture|Expedition|Delivery|CommandeFournisseur|FactureFournisseur|SupplierProposal $object @phan-var-force PropaleLigne|ContratLigne|CommonObjectLine|CommonInvoiceLine|CommonOrderLine|ExpeditionLigne|DeliveryLine|FactureFournisseurLigneRec|SupplierInvoiceLine|SupplierProposalLine $line @@ -117,7 +116,7 @@ $coldisplay = 0; ?> - + - + element == 'commande' && isModEnabled('stock') && isModEnabled('shipping') && !getDolGlobalString('ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD') && ($object->status > 0 && $object->status < 3)) { + print ''; + print ' '; + print ''; + } + ?> lines) && $i > 0) { + // @phan-suppress-next-line PhanUndeclaredGlobalVariable for ($j = $i - 1; $j >= 0; $j--) { $lastline = $object->lines[$j]; if ($lastline->product_type == Product::TYPE_SERVICE && (!empty($lastline->date_start) || !empty($lastline->date_end))) { diff --git a/htdocs/core/tpl/objectline_title.tpl.php b/htdocs/core/tpl/objectline_title.tpl.php index 0e454d8866b..b74717a5119 100644 --- a/htdocs/core/tpl/objectline_title.tpl.php +++ b/htdocs/core/tpl/objectline_title.tpl.php @@ -137,6 +137,11 @@ if (isModEnabled("multicurrency") && $this->multicurrency_code && $this->multicu // Qty print ''.$langs->trans('Qty').''; +//ShippableStatus +if ($object->element == 'commande' && isModEnabled('stock') && isModEnabled('shipping') && !getDolGlobalString('ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD') && ($object->status > 0 && $object->status < 3)) { + print ''.$langs->trans("ShippableStatus").''; +} + // Unit if (getDolGlobalString('PRODUCT_USE_UNITS')) { print ''.$langs->trans('Unit').''; diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index dd51d9b7df0..e4fe0d3a485 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -83,7 +83,7 @@ if (defined('SUBTOTALS_SPECIAL_CODE') && $line->special_code == SUBTOTALS_SPECIA return require DOL_DOCUMENT_ROOT.'/core/tpl/subtotal_view.tpl.php'; } -global $mysoc; +global $mysoc, $db; global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax; $usemargins = 0; @@ -462,7 +462,40 @@ if ((($line->info_bits & 2) != 2) && $line->special_code != 3) { print ' '; } print ''; +//Shippable Status +if ($object->element == 'commande' && isModEnabled('stock') && isModEnabled('shipping') && !getDolGlobalString('ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD') && ($object->status > 0 && $object->status < 3)) { + $coldisplay++; + print ''; + + if ($line->fk_product > 0 && $line->product_type == 0) { + static $productstatcache = array(); + + if (empty($productstatcache[$line->fk_product])) { + $prod = new Product($this->db); + $prod->fetch($line->fk_product); + $prod->load_stock('nobatch,warehouseopen'); + $productstatcache[$line->fk_product]['stockreel'] = $prod->stock_reel; + } + $stock = $productstatcache[$line->fk_product]['stockreel']; + $reliquat = $line->qty; + if (!empty($object->expeditions[$line->id])) { + $reliquat -= $object->expeditions[$line->id]; + } + if ($reliquat > 0) { + if ($stock >= $reliquat) { + print img_picto($langs->trans("Stock").': '.$stock, 'dolly', '', 0, 0, 0, '', 'green'); + } else { + print img_picto($langs->trans("Stock").': '.$stock, 'dolly', '', 0, 0, 0, '', 'error'); + } + } else { + print img_picto($langs->trans("Shipped"), 'statut5'); + } + } else { + print ' '; + } + print ''; +} if (getDolGlobalString('PRODUCT_USE_UNITS')) { print ''; $label = $line->getLabelOfUnit('short', $langs); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 0309619949b..5c3cd8c98f2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1551,6 +1551,7 @@ InvoiceOptionCategoryOfOperationsYes1=Yes, below the address block InvoiceOptionCategoryOfOperationsYes2=Yes, in the lower left-hand corner InvoiceClassifyBilledSupplierOrderWithoutInvoice=Disallow the classification of an order as billed without invoice. InvoiceClassifyBilledSupplierOrderWithoutInvoiceHelp=An order can be classified as billed by default. If this conf is set to true, it will be not. +EnableShippableIconOnCard=Enable shippable icon on order card ##### Supplier Orders ##### SupplierOrderClassifyBilledWithoutInvoice=Disallow the classification of a purchase order as billed without invoice. SupplierOrderClassifyBilledWithoutInvoiceHelp=A supplier order can be classified as billed by default. If this conf is set to true, it will be not. diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index ecc7286b13d..3b593212db0 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -398,6 +398,8 @@ PriceUHT=U.P. (net) PriceUHTCurrency=U.P (net) (currency) PriceUTTC=U.P. (inc. tax) PriceUTTCCurrency=U.P (inc. tax) (currency) +ShippableStatus=Shippable +Shipped=Shipped Amount=Amount Amounts=Amounts AmountInvoice=Invoice amount