66namespace Magento \Catalog \Model \ResourceModel \Product ;
77
88use Magento \Catalog \Api \Data \ProductInterface ;
9+ use Magento \Framework \DataObject ;
10+ use Magento \Framework \Model \AbstractModel ;
911use Magento \Store \Model \ScopeInterface ;
12+ use Magento \Store \Model \Store ;
1013
1114/**
1215 * Catalog product custom option resource model
@@ -77,10 +80,10 @@ protected function _construct()
7780 /**
7881 * Save options store data
7982 *
80- * @param \Magento\Framework\Model\ AbstractModel $object
83+ * @param AbstractModel $object
8184 * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
8285 */
83- protected function _afterSave (\ Magento \ Framework \ Model \ AbstractModel $ object )
86+ protected function _afterSave (AbstractModel $ object )
8487 {
8588 $ this ->_saveValuePrices ($ object );
8689 $ this ->_saveValueTitles ($ object );
@@ -91,138 +94,38 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
9194 /**
9295 * Save value prices
9396 *
94- * @param \Magento\Framework\Model\ AbstractModel $object
97+ * @param AbstractModel $object
9598 * @return $this
96- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
97- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
9899 */
99- protected function _saveValuePrices (\ Magento \ Framework \ Model \ AbstractModel $ object )
100+ protected function _saveValuePrices (AbstractModel $ object )
100101 {
101- $ priceTable = $ this ->getTable ('catalog_product_option_price ' );
102- $ connection = $ this ->getConnection ();
103-
104102 /*
105103 * Better to check param 'price' and 'price_type' for saving.
106104 * If there is not price skip saving price
107105 */
108-
109106 if (in_array ($ object ->getType (), $ this ->getPriceTypes ())) {
110- //save for store_id = 0
107+ // save for store_id = 0
111108 if (!$ object ->getData ('scope ' , 'price ' )) {
112- $ statement = $ connection ->select ()->from (
113- $ priceTable ,
114- 'option_id '
115- )->where (
116- 'option_id = ? ' ,
117- $ object ->getId ()
118- )->where (
119- 'store_id = ? ' ,
120- \Magento \Store \Model \Store::DEFAULT_STORE_ID
121- );
122- $ optionId = $ connection ->fetchOne ($ statement );
123-
124- if ($ optionId ) {
125- $ data = $ this ->_prepareDataForTable (
126- new \Magento \Framework \DataObject (
127- ['price ' => $ object ->getPrice (), 'price_type ' => $ object ->getPriceType ()]
128- ),
129- $ priceTable
130- );
131-
132- $ connection ->update (
133- $ priceTable ,
134- $ data ,
135- [
136- 'option_id = ? ' => $ object ->getId (),
137- 'store_id = ? ' => \Magento \Store \Model \Store::DEFAULT_STORE_ID
138- ]
139- );
140- } else {
141- $ data = $ this ->_prepareDataForTable (
142- new \Magento \Framework \DataObject (
143- [
144- 'option_id ' => $ object ->getId (),
145- 'store_id ' => \Magento \Store \Model \Store::DEFAULT_STORE_ID ,
146- 'price ' => $ object ->getPrice (),
147- 'price_type ' => $ object ->getPriceType (),
148- ]
149- ),
150- $ priceTable
151- );
152- $ connection ->insert ($ priceTable , $ data );
153- }
109+ $ this ->savePriceByStore ($ object , Store::DEFAULT_STORE_ID );
154110 }
155111
156112 $ scope = (int )$ this ->_config ->getValue (
157- \ Magento \ Store \ Model \ Store::XML_PATH_PRICE_SCOPE ,
158- ScopeInterface::SCOPE_STORE
113+ Store::XML_PATH_PRICE_SCOPE ,
114+ \ Magento \ Store \ Model \ ScopeInterface::SCOPE_STORE
159115 );
160116
161- if ($ object ->getStoreId () != '0 ' && $ scope == \Magento \Store \Model \Store::PRICE_SCOPE_WEBSITE ) {
162- $ website = $ this ->_storeManager ->getStore ($ object ->getStoreId ())->getWebsite ();
163-
164- $ websiteBaseCurrency = $ this ->_config ->getValue (
165- \Magento \Directory \Model \Currency::XML_PATH_CURRENCY_BASE ,
166- ScopeInterface::SCOPE_WEBSITE ,
167- $ website
168- );
169-
170- $ storeIds = $ website ->getStoreIds ();
171- if (is_array ($ storeIds )) {
172- foreach ($ storeIds as $ storeId ) {
173- if ($ object ->getPriceType () == 'fixed ' ) {
174- $ storeCurrency = $ this ->_storeManager ->getStore ($ storeId )->getBaseCurrencyCode ();
175- $ rate = $ this ->_currencyFactory ->create ()->load ($ websiteBaseCurrency )
176- ->getRate ($ storeCurrency );
177- $ rate ?: $ rate = 1 ;
178- $ newPrice = $ object ->getPrice () * $ rate ;
179- } else {
180- $ newPrice = $ object ->getPrice ();
181- }
182-
183- $ statement = $ connection ->select ()->from (
184- $ priceTable
185- )->where (
186- 'option_id = ? ' ,
187- $ object ->getId ()
188- )->where (
189- 'store_id = ? ' ,
190- $ storeId
191- );
192-
193- if ($ connection ->fetchOne ($ statement )) {
194- $ data = $ this ->_prepareDataForTable (
195- new \Magento \Framework \DataObject (
196- ['price ' => $ newPrice , 'price_type ' => $ object ->getPriceType ()]
197- ),
198- $ priceTable
199- );
200-
201- $ connection ->update (
202- $ priceTable ,
203- $ data ,
204- ['option_id = ? ' => $ object ->getId (), 'store_id = ? ' => $ storeId ]
205- );
206- } else {
207- $ data = $ this ->_prepareDataForTable (
208- new \Magento \Framework \DataObject (
209- [
210- 'option_id ' => $ object ->getId (),
211- 'store_id ' => $ storeId ,
212- 'price ' => $ newPrice ,
213- 'price_type ' => $ object ->getPriceType (),
214- ]
215- ),
216- $ priceTable
217- );
218- $ connection ->insert ($ priceTable , $ data );
219- }
220- }
117+ if ($ object ->getStoreId () != '0 ' && $ scope == Store::PRICE_SCOPE_WEBSITE ) {
118+ $ storeIds = $ this ->_storeManager ->getStore ($ object ->getStoreId ())->getWebsite ()->getStoreIds ();
119+ if (empty ($ storeIds )) {
120+ return $ this ;
121+ }
122+ foreach ($ storeIds as $ storeId ) {
123+ $ newPrice = $ this ->calculateStorePrice ($ object , $ storeId );
124+ $ this ->savePriceByStore ($ object , (int )$ storeId , $ newPrice );
221125 }
222- } elseif ($ scope == \Magento \Store \Model \Store::PRICE_SCOPE_WEBSITE && $ object ->getData ('scope ' , 'price ' )
223- ) {
224- $ connection ->delete (
225- $ priceTable ,
126+ } elseif ($ scope == Store::PRICE_SCOPE_WEBSITE && $ object ->getData ('scope ' , 'price ' )) {
127+ $ this ->getConnection ()->delete (
128+ $ this ->getTable ('catalog_product_option_price ' ),
226129 ['option_id = ? ' => $ object ->getId (), 'store_id = ? ' => $ object ->getStoreId ()]
227130 );
228131 }
@@ -231,31 +134,114 @@ protected function _saveValuePrices(\Magento\Framework\Model\AbstractModel $obje
231134 return $ this ;
232135 }
233136
137+ /**
138+ * Save option price by store
139+ *
140+ * @param AbstractModel $object
141+ * @param int $storeId
142+ * @param float|null $newPrice
143+ */
144+ private function savePriceByStore (AbstractModel $ object , int $ storeId , float $ newPrice = null ): void
145+ {
146+ $ priceTable = $ this ->getTable ('catalog_product_option_price ' );
147+ $ connection = $ this ->getConnection ();
148+ $ price = $ newPrice === null ? $ object ->getPrice () : $ newPrice ;
149+
150+ $ statement = $ connection ->select ()->from ($ priceTable , 'option_id ' )
151+ ->where ('option_id = ? ' , $ object ->getId ())
152+ ->where ('store_id = ? ' , $ storeId );
153+ $ optionId = $ connection ->fetchOne ($ statement );
154+
155+ if (!$ optionId ) {
156+ $ data = $ this ->_prepareDataForTable (
157+ new DataObject (
158+ [
159+ 'option_id ' => $ object ->getId (),
160+ 'store_id ' => $ storeId ,
161+ 'price ' => $ price ,
162+ 'price_type ' => $ object ->getPriceType (),
163+ ]
164+ ),
165+ $ priceTable
166+ );
167+ $ connection ->insert ($ priceTable , $ data );
168+ } else {
169+ // skip to update the default price when the store price is saving
170+ if ($ storeId === Store::DEFAULT_STORE_ID && (int )$ object ->getStoreId () !== $ storeId ) {
171+ return ;
172+ }
173+
174+ $ data = $ this ->_prepareDataForTable (
175+ new DataObject (
176+ [
177+ 'price ' => $ price ,
178+ 'price_type ' => $ object ->getPriceType ()
179+ ]
180+ ),
181+ $ priceTable
182+ );
183+
184+ $ connection ->update (
185+ $ priceTable ,
186+ $ data ,
187+ [
188+ 'option_id = ? ' => $ object ->getId (),
189+ 'store_id = ? ' => $ storeId
190+ ]
191+ );
192+ }
193+ }
194+
195+ /**
196+ * Calculate price by store
197+ *
198+ * @param AbstractModel $object
199+ * @param int $storeId
200+ * @return float
201+ */
202+ private function calculateStorePrice (AbstractModel $ object , int $ storeId ): float
203+ {
204+ $ price = $ object ->getPrice ();
205+ if ($ object ->getPriceType () == 'fixed ' ) {
206+ $ website = $ this ->_storeManager ->getStore ($ storeId )->getWebsite ();
207+ $ websiteBaseCurrency = $ this ->_config ->getValue (
208+ \Magento \Directory \Model \Currency::XML_PATH_CURRENCY_BASE ,
209+ ScopeInterface::SCOPE_WEBSITE ,
210+ $ website
211+ );
212+ $ storeCurrency = $ this ->_storeManager ->getStore ($ storeId )->getBaseCurrencyCode ();
213+ $ rate = $ this ->_currencyFactory ->create ()->load ($ websiteBaseCurrency )->getRate ($ storeCurrency );
214+ $ price = $ object ->getPrice () * ($ rate ?: 1 );
215+ }
216+
217+ return (float )$ price ;
218+ }
219+
234220 /**
235221 * Save titles
236222 *
237- * @param \Magento\Framework\Model\ AbstractModel $object
223+ * @param AbstractModel $object
238224 * @return void
239225 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
240226 */
241- protected function _saveValueTitles (\ Magento \ Framework \ Model \ AbstractModel $ object )
227+ protected function _saveValueTitles (AbstractModel $ object )
242228 {
243229 $ connection = $ this ->getConnection ();
244230 $ titleTableName = $ this ->getTable ('catalog_product_option_title ' );
245- foreach ([\ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID , $ object ->getStoreId ()] as $ storeId ) {
231+ foreach ([Store::DEFAULT_STORE_ID , $ object ->getStoreId ()] as $ storeId ) {
246232 $ existInCurrentStore = $ this ->getColFromOptionTable ($ titleTableName , (int )$ object ->getId (), (int )$ storeId );
247- $ existInDefaultStore = (int )$ storeId == \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID ?
233+ $ existInDefaultStore = (int )$ storeId == Store::DEFAULT_STORE_ID ?
248234 $ existInCurrentStore :
249235 $ this ->getColFromOptionTable (
250236 $ titleTableName ,
251237 (int )$ object ->getId (),
252- \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID
238+ Store::DEFAULT_STORE_ID
253239 );
254240
255241 if ($ object ->getTitle ()) {
256242 $ isDeleteStoreTitle = (bool )$ object ->getData ('is_delete_store_title ' );
257243 if ($ existInCurrentStore ) {
258- if ($ isDeleteStoreTitle && (int )$ storeId != \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID ) {
244+ if ($ isDeleteStoreTitle && (int )$ storeId != Store::DEFAULT_STORE_ID ) {
259245 $ connection ->delete ($ titleTableName , ['option_title_id = ? ' => $ existInCurrentStore ]);
260246 } elseif ($ object ->getStoreId () == $ storeId ) {
261247 $ data = $ this ->_prepareDataForTable (
@@ -273,9 +259,9 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
273259 }
274260 } else {
275261 // we should insert record into not default store only of if it does not exist in default store
276- if (($ storeId == \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID && !$ existInDefaultStore ) ||
262+ if (($ storeId == Store::DEFAULT_STORE_ID && !$ existInDefaultStore ) ||
277263 (
278- $ storeId != \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID &&
264+ $ storeId != Store::DEFAULT_STORE_ID &&
279265 !$ existInCurrentStore &&
280266 !$ isDeleteStoreTitle
281267 )
@@ -294,7 +280,7 @@ protected function _saveValueTitles(\Magento\Framework\Model\AbstractModel $obje
294280 }
295281 }
296282 } else {
297- if ($ object ->getId () && $ object ->getStoreId () > \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID
283+ if ($ object ->getId () && $ object ->getStoreId () > Store::DEFAULT_STORE_ID
298284 && $ storeId
299285 ) {
300286 $ connection ->delete (
@@ -473,7 +459,7 @@ public function getSearchableData($productId, $storeId)
473459 'option_title_default.option_id=product_option.option_id ' ,
474460 $ connection ->quoteInto (
475461 'option_title_default.store_id = ? ' ,
476- \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID
462+ Store::DEFAULT_STORE_ID
477463 )
478464 ]
479465 );
@@ -520,7 +506,7 @@ public function getSearchableData($productId, $storeId)
520506 'option_title_default.option_type_id=option_type.option_type_id ' ,
521507 $ connection ->quoteInto (
522508 'option_title_default.store_id = ? ' ,
523- \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID
509+ Store::DEFAULT_STORE_ID
524510 )
525511 ]
526512 );
@@ -585,7 +571,7 @@ public function getPriceTypes()
585571 }
586572
587573 /**
588- * Returns metadata poll.
574+ * Get Metadata Pool
589575 *
590576 * @return \Magento\Framework\EntityManager\MetadataPool
591577 */
0 commit comments