@@ -117,7 +117,7 @@ public function create( $fields, Order $order = null )
117117 * check discount validity and throw an
118118 * error is something is not set correctly.
119119 */
120- $ this ->__checkDiscountVality ( $ fields );
120+ $ this ->__checkDiscountValidity ( $ fields );
121121
122122 /**
123123 * check delivery informations before
@@ -150,7 +150,7 @@ public function create( $fields, Order $order = null )
150150 /**
151151 * if we're editing an order. We need to loop the products in order
152152 * to recover all the products that has been deleted from the POS and therefore
153- * aren't tracked no more.
153+ * aren't tracked no more. This also make stock adjustment for product which has changed.
154154 */
155155 $ this ->__deleteUntrackedProducts ( $ order , $ fields [ 'products ' ] );
156156
@@ -486,9 +486,8 @@ public function __deleteUntrackedProducts( $order, $products )
486486 {
487487 if ( $ order instanceof Order ) {
488488 $ ids = collect ( $ products )
489- ->filter ( fn ( $ product ) => isset ( $ product [ 'id ' ] ) )
490- ->map ( fn ( $ product ) => $ product [ 'id ' ] . '- ' . $ product [ 'unit_id ' ] ?? false )
491- ->filter ( fn ( $ product ) => $ product !== false )
489+ ->filter ( fn ( $ product ) => isset ( $ product [ 'id ' ] ) && isset ( $ product [ 'unit_id ' ] ) )
490+ ->map ( fn ( $ product ) => $ product [ 'id ' ] . '- ' . $ product [ 'unit_id ' ] )
492491 ->toArray ();
493492
494493 /**
@@ -498,34 +497,44 @@ public function __deleteUntrackedProducts( $order, $products )
498497 */
499498 if ( $ order ->payment_status !== Order::PAYMENT_HOLD ) {
500499 $ order ->products ->map ( function ( OrderProduct $ product ) use ( $ products ) {
501- $ products = collect ( $ products )
502- ->filter ( fn ( $ product ) => isset ( $ product [ 'id ' ] ) )
503- ->mapWithKeys ( fn ( $ product ) => [ $ product [ 'id ' ] => $ product ] )
504- ->toArray ();
505-
506- if ( in_array ( $ product ->id , array_keys ( $ products ) ) ) {
507- if ( $ product ->quantity < $ products [ $ product ->id ][ 'quantity ' ] ) {
508- return [
509- 'operation ' => 'add ' ,
510- 'unit_price ' => $ products [ $ product ->id ][ 'unit_price ' ],
511- 'total_price ' => $ products [ $ product ->id ][ 'total_price ' ],
512- 'quantity ' => $ products [ $ product ->id ][ 'quantity ' ] - $ product ->quantity ,
513- 'orderProduct ' => $ product ,
514- ];
515- } elseif ( $ product ->quantity > $ products [ $ product ->id ][ 'quantity ' ] ) {
516- return [
517- 'operation ' => 'remove ' ,
518- 'unit_price ' => $ products [ $ product ->id ][ 'unit_price ' ],
519- 'total_price ' => $ products [ $ product ->id ][ 'total_price ' ],
520- 'quantity ' => $ product ->quantity - $ products [ $ product ->id ][ 'quantity ' ],
521- 'orderProduct ' => $ product ,
522- ];
500+ $ productHistory = ProductHistory::where ( 'operation_type ' , ProductHistory::ACTION_SOLD )
501+ ->where ( 'order_product_id ' , $ product ->id )
502+ ->first ();
503+
504+ /**
505+ * We should restore or retreive quantities when the
506+ * product has initially be marked as sold.
507+ */
508+ if ( $ productHistory instanceof ProductHistory ) {
509+ $ products = collect ( $ products )
510+ ->filter ( fn ( $ product ) => isset ( $ product [ 'id ' ] ) )
511+ ->mapWithKeys ( fn ( $ product ) => [ $ product [ 'id ' ] => $ product ] )
512+ ->toArray ();
513+
514+ if ( in_array ( $ product ->id , array_keys ( $ products ) ) ) {
515+ if ( $ product ->quantity < $ products [ $ product ->id ][ 'quantity ' ] ) {
516+ return [
517+ 'operation ' => 'add ' ,
518+ 'unit_price ' => $ products [ $ product ->id ][ 'unit_price ' ],
519+ 'total_price ' => $ products [ $ product ->id ][ 'total_price ' ],
520+ 'quantity ' => $ products [ $ product ->id ][ 'quantity ' ] - $ product ->quantity ,
521+ 'orderProduct ' => $ product ,
522+ ];
523+ } elseif ( $ product ->quantity > $ products [ $ product ->id ][ 'quantity ' ] ) {
524+ return [
525+ 'operation ' => 'remove ' ,
526+ 'unit_price ' => $ products [ $ product ->id ][ 'unit_price ' ],
527+ 'total_price ' => $ products [ $ product ->id ][ 'total_price ' ],
528+ 'quantity ' => $ product ->quantity - $ products [ $ product ->id ][ 'quantity ' ],
529+ 'orderProduct ' => $ product ,
530+ ];
531+ }
523532 }
524533 }
525534
526535 /**
527- * when to change has been made on
528- * the order product
536+ * When no changes has been made
537+ * on the orde product.
529538 */
530539 return false ;
531540 })
@@ -626,7 +635,7 @@ private function __getShippingFee($fields): float
626635 *
627636 * @throws NotAllowedException
628637 */
629- public function __checkDiscountVality ( $ fields )
638+ public function __checkDiscountValidity ( $ fields )
630639 {
631640 if (! empty (@$ fields ['discount_type ' ])) {
632641 if ($ fields ['discount_type ' ] === 'percentage ' && (floatval ($ fields ['discount_percentage ' ]) < 0 ) || (floatval ($ fields ['discount_percentage ' ]) > 100 )) {
@@ -1035,15 +1044,12 @@ private function __saveOrderProducts($order, $products)
10351044
10361045 $ orderProducts = $ products ->map (function ($ product ) use (&$ subTotal , &$ taxes , &$ order , &$ gross ) {
10371046
1038- $ previousQuantity = 0 ;
1039-
10401047 /**
10411048 * if the product id is provided
10421049 * then we can use that id as a reference.
10431050 */
10441051 if ( isset ( $ product [ 'id ' ] ) ) {
10451052 $ orderProduct = OrderProduct::find ( $ product [ 'id ' ] );
1046- $ previousQuantity = $ orderProduct ->quantity ;
10471053 } else {
10481054 $ orderProduct = new OrderProduct ;
10491055 }
@@ -1124,10 +1130,13 @@ private function __saveOrderProducts($order, $products)
11241130 * already exists and which are edited. We'll here only records
11251131 * products that doesn't exists yet.
11261132 */
1127- if ( $ orderProduct ->wasRecentlyCreated ) {
1133+ $ stockHistoryExists = ProductHistory::where ( 'order_product_id ' , $ orderProduct ->id )
1134+ ->where ( 'operation_type ' , ProductHistory::ACTION_SOLD )
1135+ ->count () === 1 ;
1136+
1137+ if ( ! $ stockHistoryExists ) {
11281138 $ this ->productService ->stockAdjustment ( ProductHistory::ACTION_SOLD , $ history );
11291139 }
1130-
11311140 }
11321141
11331142 event ( new OrderProductAfterSavedEvent ( $ orderProduct , $ order , $ product ) );
@@ -1150,11 +1159,11 @@ private function __buildOrderProducts( $products )
11501159 $ product = null ;
11511160 $ productUnitQuantity = null ;
11521161
1153- if ( ! empty ( $ orderProduct [ 'sku ' ] ) || ! empty ( $ orderProduct [ 'product_id ' ] ) ) {
1162+ if ( ! empty ( $ orderProduct [ 'sku ' ] ?? null ) || ! empty ( $ orderProduct [ 'product_id ' ] ?? null ) ) {
11541163 $ product = Cache::remember ( 'store- ' . ( $ orderProduct ['product_id ' ] ?? $ orderProduct ['sku ' ] ), 60 , function () use ($ orderProduct ) {
1155- if (! empty (@ $ orderProduct ['product_id ' ]) ) {
1164+ if ( ! empty ( $ orderProduct ['product_id ' ] ?? null ) ) {
11561165 return $ this ->productService ->get ($ orderProduct ['product_id ' ]);
1157- } elseif (! empty (@ $ orderProduct ['sku ' ]) ) {
1166+ } elseif ( ! empty ( $ orderProduct ['sku ' ] ?? null ) ) {
11581167 return $ this ->productService ->getProductUsingSKUOrFail ($ orderProduct ['sku ' ]);
11591168 }
11601169 });
@@ -1298,14 +1307,24 @@ public function checkQuantityAvailability( $product, $productUnitQuantity, $orde
12981307 * we want to deduct from the stock, we need to know wether the quantity has changed (greater or not). We then need to pull
12991308 * the original reference of the orderProduct to compute the new quantity that will be deducted from inventory.
13001309 */
1310+ $ quantityToIgnore = 0 ;
1311+
13011312 if ( isset ( $ orderProduct [ 'id ' ] ) ) {
1302- $ orderProductRerefence = OrderProduct::find ( $ orderProduct [ 'id ' ] );
1303- $ orderProductQuantity = $ this ->mathService ->set ( $ orderProductRerefence ->quantity )
1304- ->minus ( $ orderProduct [ 'quantity ' ] )
1305- ->toFloat ();
1313+ $ stockWasDeducted = ProductHistory::where ( 'order_product_id ' , $ orderProduct [ 'id ' ] )
1314+ ->where ( 'operation_type ' , ProductHistory::ACTION_SOLD )
1315+ ->count () === 1 ;
1316+
1317+ /**
1318+ * Only when the stock was deducted, we'll ignore the quantity
1319+ * that is currently in use by the order product.
1320+ */
1321+ if ( $ stockWasDeducted ) {
1322+ $ orderProductRerefence = OrderProduct::find ( $ orderProduct [ 'id ' ] );
1323+ $ quantityToIgnore = $ orderProductRerefence ->quantity ;
1324+ }
13061325 }
13071326
1308- if ( $ productUnitQuantity ->quantity - $ storageQuantity < abs ( $ orderProductQuantity ) ) {
1327+ if ( ( $ productUnitQuantity ->quantity + $ quantityToIgnore ) - $ storageQuantity < abs ( $ orderProductQuantity ) ) {
13091328 throw new \Exception (
13101329 sprintf (
13111330 __ ( 'Unable to proceed, there is not enough stock for %s using the unit %s. Requested : %s, available %s ' ),
0 commit comments