@@ -145,207 +145,226 @@ public async Task<Result<Order>> CreateOrder(Guid checkoutId, string paymentMeth
145145 }
146146
147147 public async Task < Result < Order > > CreateOrder ( Guid checkoutId , string paymentMethod , decimal paymentFeeAmount , string shippingMethodName , Address billingAddress , Address shippingAddress , OrderStatus orderStatus = OrderStatus . New )
148- {
149- var checkout = _checkoutRepository
150- . Query ( )
151- . Include ( c => c . CheckoutItems ) . ThenInclude ( x => x . Product )
152- . Include ( c => c . Customer )
153- . Include ( c => c . CreatedBy )
154- . Where ( x => x . Id == checkoutId ) . FirstOrDefault ( ) ;
148+ {
149+ var checkout = _checkoutRepository
150+ . Query ( )
151+ . Include ( c => c . CheckoutItems ) . ThenInclude ( x => x . Product )
152+ . Include ( c => c . Customer )
153+ . Include ( c => c . CreatedBy )
154+ . Where ( x => x . Id == checkoutId ) . FirstOrDefault ( ) ;
155+
156+ if ( checkout == null )
157+ {
158+ return Result . Fail < Order > ( $ "Checkout id { checkoutId } cannot be found") ;
159+ }
155160
156- if ( checkout == null )
161+ var checkingDiscountResult = await CheckForDiscountIfAny ( checkout ) ;
162+ if ( ! checkingDiscountResult . Succeeded )
163+ {
164+ return Result . Fail < Order > ( checkingDiscountResult . ErrorMessage ) ;
165+ }
166+
167+ var validateShippingMethodResult = await ValidateShippingMethod ( shippingMethodName , shippingAddress , checkout ) ;
168+ if ( ! validateShippingMethodResult . Success )
169+ {
170+ return Result . Fail < Order > ( validateShippingMethodResult . Error ) ;
171+ }
172+
173+ var shippingMethod = validateShippingMethodResult . Value ;
174+
175+ var orderBillingAddress = new OrderAddress ( )
176+ {
177+ AddressLine1 = billingAddress . AddressLine1 ,
178+ AddressLine2 = billingAddress . AddressLine2 ,
179+ ContactName = billingAddress . ContactName ,
180+ CountryId = billingAddress . CountryId ,
181+ StateOrProvinceId = billingAddress . StateOrProvinceId ,
182+ DistrictId = billingAddress . DistrictId ,
183+ City = billingAddress . City ,
184+ ZipCode = billingAddress . ZipCode ,
185+ Phone = billingAddress . Phone
186+ } ;
187+
188+ var orderShippingAddress = new OrderAddress ( )
189+ {
190+ AddressLine1 = shippingAddress . AddressLine1 ,
191+ AddressLine2 = shippingAddress . AddressLine2 ,
192+ ContactName = shippingAddress . ContactName ,
193+ CountryId = shippingAddress . CountryId ,
194+ StateOrProvinceId = shippingAddress . StateOrProvinceId ,
195+ DistrictId = shippingAddress . DistrictId ,
196+ City = shippingAddress . City ,
197+ ZipCode = shippingAddress . ZipCode ,
198+ Phone = shippingAddress . Phone
199+ } ;
200+
201+ var order = new Order
202+ {
203+ Customer = checkout . Customer ,
204+ CreatedOn = DateTimeOffset . Now ,
205+ CreatedBy = checkout . CreatedBy ,
206+ LatestUpdatedOn = DateTimeOffset . Now ,
207+ LatestUpdatedById = checkout . CreatedById ,
208+ BillingAddress = orderBillingAddress ,
209+ ShippingAddress = orderShippingAddress ,
210+ PaymentMethod = paymentMethod ,
211+ PaymentFeeAmount = paymentFeeAmount
212+ } ;
213+
214+ using ( var transaction = _dbContext . Database . BeginTransaction ( ) )
215+ {
216+ foreach ( var checkoutItem in checkout . CheckoutItems )
217+ {
218+ if ( ! checkoutItem . Product . IsAllowToOrder || ! checkoutItem . Product . IsPublished || checkoutItem . Product . IsDeleted )
157219 {
158- return Result . Fail < Order > ( $ "Checkout id { checkoutId } cannot be found ") ;
220+ return Result . Fail < Order > ( $ "The product { checkoutItem . Product . Name } is not available any more ") ;
159221 }
160222
161- var checkingDiscountResult = await CheckForDiscountIfAny ( checkout ) ;
162- if ( ! checkingDiscountResult . Succeeded )
223+ var product = _dbContext . Products
224+ . Where ( p => p . Id == checkoutItem . ProductId )
225+ . FirstOrDefault ( ) ;
226+
227+ if ( product == null )
163228 {
164- return Result . Fail < Order > ( checkingDiscountResult . ErrorMessage ) ;
229+ return Result . Fail < Order > ( "Product not found" ) ;
165230 }
166231
167- var validateShippingMethodResult = await ValidateShippingMethod ( shippingMethodName , shippingAddress , checkout ) ;
168- if ( ! validateShippingMethodResult . Success )
232+ if ( product . StockTrackingIsEnabled )
169233 {
170- return Result . Fail < Order > ( validateShippingMethodResult . Error ) ;
234+ _dbContext . Products
235+ . Where ( p => p . Id == checkoutItem . ProductId )
236+ . ForUpdate ( )
237+ . FirstOrDefault ( ) ;
238+
239+ if ( product . StockQuantity < checkoutItem . Quantity )
240+ {
241+ return Result . Fail < Order > ( $ "There are only { product . StockQuantity } items available for { product . Name } ") ;
242+ }
243+
244+ product . StockQuantity -= checkoutItem . Quantity ;
245+ _dbContext . SaveChanges ( ) ;
171246 }
172247
173- var shippingMethod = validateShippingMethodResult . Value ;
248+ var taxPercent = await _taxService . GetTaxPercent ( checkoutItem . Product . TaxClassId , shippingAddress . CountryId , shippingAddress . StateOrProvinceId , shippingAddress . ZipCode ) ;
249+
250+ var calculatedProductPrice = _productPricingService . CalculateProductPrice ( checkoutItem . Product ) ;
174251
175- var orderBillingAddress = new OrderAddress ( )
252+ var productPrice = calculatedProductPrice . OldPrice ?? calculatedProductPrice . Price ;
253+ if ( checkout . IsProductPriceIncludeTax )
176254 {
177- AddressLine1 = billingAddress . AddressLine1 ,
178- AddressLine2 = billingAddress . AddressLine2 ,
179- ContactName = billingAddress . ContactName ,
180- CountryId = billingAddress . CountryId ,
181- StateOrProvinceId = billingAddress . StateOrProvinceId ,
182- DistrictId = billingAddress . DistrictId ,
183- City = billingAddress . City ,
184- ZipCode = billingAddress . ZipCode ,
185- Phone = billingAddress . Phone
186- } ;
255+ productPrice = productPrice / ( 1 + ( taxPercent / 100 ) ) ;
256+ }
187257
188- var orderShippingAddress = new OrderAddress ( )
258+ var orderItem = new OrderItem
189259 {
190- AddressLine1 = shippingAddress . AddressLine1 ,
191- AddressLine2 = shippingAddress . AddressLine2 ,
192- ContactName = shippingAddress . ContactName ,
193- CountryId = shippingAddress . CountryId ,
194- StateOrProvinceId = shippingAddress . StateOrProvinceId ,
195- DistrictId = shippingAddress . DistrictId ,
196- City = shippingAddress . City ,
197- ZipCode = shippingAddress . ZipCode ,
198- Phone = shippingAddress . Phone
260+ Product = checkoutItem . Product ,
261+ ProductPrice = productPrice ,
262+ Quantity = checkoutItem . Quantity ,
263+ TaxPercent = taxPercent ,
264+ TaxAmount = checkoutItem . Quantity * ( productPrice * taxPercent / 100 )
199265 } ;
200266
201- var order = new Order
267+ var discountedItem = checkingDiscountResult . DiscountedProducts . FirstOrDefault ( x => x . Id == checkoutItem . ProductId ) ;
268+ if ( discountedItem != null )
202269 {
203- Customer = checkout . Customer ,
270+ orderItem . DiscountAmount = discountedItem . DiscountAmount ;
271+ }
272+
273+ if ( calculatedProductPrice . OldPrice . HasValue )
274+ {
275+ orderItem . DiscountAmount += orderItem . Quantity * ( calculatedProductPrice . OldPrice . Value - calculatedProductPrice . Price ) ;
276+ }
277+
278+ order . AddOrderItem ( orderItem ) ;
279+ }
280+
281+ order . OrderStatus = orderStatus ;
282+ order . OrderNote = checkout . OrderNote ;
283+ order . CouponCode = checkingDiscountResult . CouponCode ;
284+ order . CouponRuleName = checkout . CouponRuleName ;
285+ order . DiscountAmount = checkingDiscountResult . DiscountAmount + order . OrderItems . Sum ( x => x . DiscountAmount ) ;
286+ order . ShippingFeeAmount = shippingMethod . Price ;
287+ order . ShippingMethod = shippingMethod . Name ;
288+ order . TaxAmount = order . OrderItems . Sum ( x => x . TaxAmount ) ;
289+ order . SubTotal = order . OrderItems . Sum ( x => x . ProductPrice * x . Quantity ) ;
290+ order . SubTotalWithDiscount = order . SubTotal - checkingDiscountResult . DiscountAmount ;
291+ order . OrderTotal = order . SubTotal + order . TaxAmount + order . ShippingFeeAmount + order . PaymentFeeAmount - order . DiscountAmount ;
292+ _orderRepository . Add ( order ) ;
293+
294+ var vendorIds = checkout . CheckoutItems . Where ( x => x . Product . VendorId . HasValue ) . Select ( x => x . Product . VendorId . Value ) . Distinct ( ) ;
295+ if ( vendorIds . Any ( ) )
296+ {
297+ order . IsMasterOrder = true ;
298+ }
299+
300+ IList < Order > subOrders = new List < Order > ( ) ;
301+ foreach ( var vendorId in vendorIds )
302+ {
303+ var subOrder = new Order
304+ {
305+ CustomerId = checkout . CustomerId ,
204306 CreatedOn = DateTimeOffset . Now ,
205- CreatedBy = checkout . CreatedBy ,
307+ CreatedById = checkout . CreatedById ,
206308 LatestUpdatedOn = DateTimeOffset . Now ,
207309 LatestUpdatedById = checkout . CreatedById ,
208310 BillingAddress = orderBillingAddress ,
209311 ShippingAddress = orderShippingAddress ,
210- PaymentMethod = paymentMethod ,
211- PaymentFeeAmount = paymentFeeAmount
312+ VendorId = vendorId ,
313+ Parent = order
212314 } ;
213315
214- foreach ( var checkoutItem in checkout . CheckoutItems )
316+ foreach ( var cartItem in checkout . CheckoutItems . Where ( x => x . Product . VendorId == vendorId ) )
215317 {
216- if ( ! checkoutItem . Product . IsAllowToOrder || ! checkoutItem . Product . IsPublished || checkoutItem . Product . IsDeleted )
217- {
218- return Result . Fail < Order > ( $ "The product { checkoutItem . Product . Name } is not available any more") ;
219- }
220-
221- if ( checkoutItem . Product . StockTrackingIsEnabled && checkoutItem . Product . StockQuantity < checkoutItem . Quantity )
222- {
223- return Result . Fail < Order > ( $ "There are only { checkoutItem . Product . StockQuantity } items available for { checkoutItem . Product . Name } ") ;
224- }
225-
226- var taxPercent = await _taxService . GetTaxPercent ( checkoutItem . Product . TaxClassId , shippingAddress . CountryId , shippingAddress . StateOrProvinceId , shippingAddress . ZipCode ) ;
227-
228- var calculatedProductPrice = _productPricingService . CalculateProductPrice ( checkoutItem . Product ) ;
229-
230- var productPrice = calculatedProductPrice . OldPrice ?? calculatedProductPrice . Price ;
318+ var taxPercent = await _taxService . GetTaxPercent ( cartItem . Product . TaxClassId , shippingAddress . CountryId , shippingAddress . StateOrProvinceId , shippingAddress . ZipCode ) ;
319+ var productPrice = cartItem . Product . Price ;
231320 if ( checkout . IsProductPriceIncludeTax )
232321 {
233322 productPrice = productPrice / ( 1 + ( taxPercent / 100 ) ) ;
234323 }
235324
236325 var orderItem = new OrderItem
237326 {
238- Product = checkoutItem . Product ,
327+ Product = cartItem . Product ,
239328 ProductPrice = productPrice ,
240- Quantity = checkoutItem . Quantity ,
329+ Quantity = cartItem . Quantity ,
241330 TaxPercent = taxPercent ,
242- TaxAmount = checkoutItem . Quantity * ( productPrice * taxPercent / 100 )
331+ TaxAmount = cartItem . Quantity * ( productPrice * taxPercent / 100 )
243332 } ;
244333
245- var discountedItem = checkingDiscountResult . DiscountedProducts . FirstOrDefault ( x => x . Id == checkoutItem . ProductId ) ;
246- if ( discountedItem != null )
247- {
248- orderItem . DiscountAmount = discountedItem . DiscountAmount ;
249- }
250-
251- if ( calculatedProductPrice . OldPrice . HasValue )
334+ if ( checkout . IsProductPriceIncludeTax )
252335 {
253- orderItem . DiscountAmount + = orderItem . Quantity * ( calculatedProductPrice . OldPrice . Value - calculatedProductPrice . Price ) ;
336+ orderItem . ProductPrice = orderItem . ProductPrice - orderItem . TaxAmount ;
254337 }
255338
256- order . AddOrderItem ( orderItem ) ;
257- if ( checkoutItem . Product . StockTrackingIsEnabled )
258- {
259- checkoutItem . Product . StockQuantity = checkoutItem . Product . StockQuantity - checkoutItem . Quantity ;
260- }
339+ subOrder . AddOrderItem ( orderItem ) ;
261340 }
262341
263- order . OrderStatus = orderStatus ;
264- order . OrderNote = checkout . OrderNote ;
265- order . CouponCode = checkingDiscountResult . CouponCode ;
266- order . CouponRuleName = checkout . CouponRuleName ;
267- order . DiscountAmount = checkingDiscountResult . DiscountAmount + order . OrderItems . Sum ( x => x . DiscountAmount ) ;
268- order . ShippingFeeAmount = shippingMethod . Price ;
269- order . ShippingMethod = shippingMethod . Name ;
270- order . TaxAmount = order . OrderItems . Sum ( x => x . TaxAmount ) ;
271- order . SubTotal = order . OrderItems . Sum ( x => x . ProductPrice * x . Quantity ) ;
272- order . SubTotalWithDiscount = order . SubTotal - checkingDiscountResult . DiscountAmount ;
273- order . OrderTotal = order . SubTotal + order . TaxAmount + order . ShippingFeeAmount + order . PaymentFeeAmount - order . DiscountAmount ;
274- _orderRepository . Add ( order ) ;
275-
276- var vendorIds = checkout . CheckoutItems . Where ( x => x . Product . VendorId . HasValue ) . Select ( x => x . Product . VendorId . Value ) . Distinct ( ) ;
277- if ( vendorIds . Any ( ) )
278- {
279- order . IsMasterOrder = true ;
280- }
342+ subOrder . SubTotal = subOrder . OrderItems . Sum ( x => x . ProductPrice * x . Quantity ) ;
343+ subOrder . TaxAmount = subOrder . OrderItems . Sum ( x => x . TaxAmount ) ;
344+ subOrder . OrderTotal = subOrder . SubTotal + subOrder . TaxAmount + subOrder . ShippingFeeAmount - subOrder . DiscountAmount ;
345+ _orderRepository . Add ( subOrder ) ;
346+ subOrders . Add ( subOrder ) ;
347+ }
281348
282- IList < Order > subOrders = new List < Order > ( ) ;
283- foreach ( var vendorId in vendorIds )
349+ using ( var transaction = _orderRepository . BeginTransaction ( ) )
350+ {
351+ _orderRepository . SaveChanges ( ) ;
352+ await _mediator . Publish ( new OrderCreated ( order ) ) ;
353+ foreach ( var subOrder in subOrders )
284354 {
285- var subOrder = new Order
286- {
287- CustomerId = checkout . CustomerId ,
288- CreatedOn = DateTimeOffset . Now ,
289- CreatedById = checkout . CreatedById ,
290- LatestUpdatedOn = DateTimeOffset . Now ,
291- LatestUpdatedById = checkout . CreatedById ,
292- BillingAddress = orderBillingAddress ,
293- ShippingAddress = orderShippingAddress ,
294- VendorId = vendorId ,
295- Parent = order
296- } ;
297-
298- foreach ( var cartItem in checkout . CheckoutItems . Where ( x => x . Product . VendorId == vendorId ) )
299- {
300- var taxPercent = await _taxService . GetTaxPercent ( cartItem . Product . TaxClassId , shippingAddress . CountryId , shippingAddress . StateOrProvinceId , shippingAddress . ZipCode ) ;
301- var productPrice = cartItem . Product . Price ;
302- if ( checkout . IsProductPriceIncludeTax )
303- {
304- productPrice = productPrice / ( 1 + ( taxPercent / 100 ) ) ;
305- }
306-
307- var orderItem = new OrderItem
308- {
309- Product = cartItem . Product ,
310- ProductPrice = productPrice ,
311- Quantity = cartItem . Quantity ,
312- TaxPercent = taxPercent ,
313- TaxAmount = cartItem . Quantity * ( productPrice * taxPercent / 100 )
314- } ;
315-
316- if ( checkout . IsProductPriceIncludeTax )
317- {
318- orderItem . ProductPrice = orderItem . ProductPrice - orderItem . TaxAmount ;
319- }
320-
321- subOrder . AddOrderItem ( orderItem ) ;
322- }
323-
324- subOrder . SubTotal = subOrder . OrderItems . Sum ( x => x . ProductPrice * x . Quantity ) ;
325- subOrder . TaxAmount = subOrder . OrderItems . Sum ( x => x . TaxAmount ) ;
326- subOrder . OrderTotal = subOrder . SubTotal + subOrder . TaxAmount + subOrder . ShippingFeeAmount - subOrder . DiscountAmount ;
327- _orderRepository . Add ( subOrder ) ;
328- subOrders . Add ( subOrder ) ;
355+ await _mediator . Publish ( new OrderCreated ( subOrder ) ) ;
329356 }
330357
331- using ( var transaction = _orderRepository . BeginTransaction ( ) )
332- {
333- _orderRepository . SaveChanges ( ) ;
334- await _mediator . Publish ( new OrderCreated ( order ) ) ;
335- foreach ( var subOrder in subOrders )
336- {
337- await _mediator . Publish ( new OrderCreated ( subOrder ) ) ;
338- }
339-
340- _couponService . AddCouponUsage ( checkout . CustomerId , order . Id , checkingDiscountResult ) ;
341- _orderRepository . SaveChanges ( ) ;
342- transaction . Commit ( ) ;
343- }
358+ _couponService . AddCouponUsage ( checkout . CustomerId , order . Id , checkingDiscountResult ) ;
359+ _orderRepository . SaveChanges ( ) ;
360+ transaction . Commit ( ) ;
361+ }
344362
345- await _mediator . Publish ( new AfterOrderCreated ( order ) ) ;
363+ await _mediator . Publish ( new AfterOrderCreated ( order ) ) ;
346364
347- return Result . Ok ( order ) ;
348- }
365+ return Result . Ok ( order ) ;
366+ }
367+ }
349368
350369 public void CancelOrder ( Order order )
351370 {
0 commit comments