Shopware 6 create product price in custom plugin: product.price vs productPrice - plugins

How do i create price for a product in custom plugin?
The database contains a table product_price but the product has also a attribute price.*price*, that confused me.
The default configuration within the product detail form price card set only the attribute product.price, entity product_price keeps empty.
Seems product.price to be a simple object, so is it done by following code? I mean, no repository needed?
// ../my_price_form.js
...
Component.register('product-pricing-configurator-form', {
...
methods: {
setPrice() {
this.product.price["c" + this.currencyId] = {
net: ...,
gross: ...,
linked: true,
listPrice: null,
currencyId: this.currencyId
regulationPrice: null
}
}
}
Questions:
What is the purpose of the entity product_price?
How do i create the product.price attribute?
Is there a documentation available about create product.price?
What about the configuration for attribute product.purchase_price? Also a simple json object?

product_price is the table for advanced pricing. These prices require a ruleId which is the id of a rule build with the rule builder. Depending on whether the rule is fulfilled and the priority these prices take precedence over the regular price (product.price) or other advanced prices.
You pretty much already got it right with the example in your question.
See the api reference here.
purchasePrices is also an instance of PriceField so it's identical in its nature to price.

Related

Microsoft Master Data Services 2016 Additonal Domain Atrribute Referencing

Is it possible to reference additional columns apart from the 'Code' and 'Name' columns when using a domain attribute in an entity?
E.g. A person entity has a code of '1' and a name of 'Smith' and a Gender of 'Male'
In a customer entity there is a domain value referencing the person entity which displays the following 1 {Smith}. The users would like an additional read only attribute which would copy the Gender value of 'Male' into the customer entity based on the domain value. Can this be done using out of the box MDS UI?
I know this is duplicate data and breaks normal form but for usability this would be useful. It would be the equivalent of referencing additional columns in an MS Access drop down list.
Many thanks in advance for any help
This is not possible with the standard UI. One option would be to develop a custom UI where you can handle these kind of requests.
If you want to stick with the standard product I can see a workaround but this is a bit of a "dirty" one.
You can misuse (abuse) the Name attribute of the Person entity by adding a business rule to the Person entity that generates the content of the Name attribute as a concatenation of multiple attributes. You of course need an additional attribute that serves as a place holder for the original Name. The concatenated field will then show in your customer entity.
One question that does come to mind is why a user would like/need to see the gender of a person in a customer list? As you have a separate Person entity I expect you to have multiple persons per customers. What would the gender of one person - even if it is the main contact - matter?

Can I rename GORM's "version" field? (Grails 2.2 + GORM MongoDB)

I've got a domain object that already has a property called versions, so I'd like to give a different name to the built-in version property (used in GORM for optimistic locking). For instance, I'd like to call it updateCount instead.
Note that I do want the semantics of optimistic locking; I just want to give the field another name. Here's what I've naively tried (and it didn't work):
class Item {
ObjectId id
static hasMany = [versions: ItemVersion]
static mapping = {
table 'item'
version column: 'updateCount' // <-- This was my attempt
}
}
I would definitely appreciate any help in...
Determining whether this is possible, and
If so, making it work :-)
Thanks!
First thing first. MongoDB (NoSQL) deals with Documents and Collections instead of Table and rows.
Being said that, the domain class should look like:
class Item {
ObjectId id
String itemName
static hasMany = [versions: ItemVersion]
static mapping = {
//Collection in Mongodb is to Table in relational world
collection 'item'
//attr in Mongodb is to column in relational world
itemName attr: 'item_name'
//After spending some time investigating it was found that
//attr for version does not make any difference
//The below would not work for implicit GORM variable "version"
//default attribute name is the variable name.
//version attr: 'updateCount'
}
}
In case you want to configure default property across the domains to switch on/off the versioning then have a look at Global Mapping Configuration.

How to use entity framework function to find certain cell

I have a table named product having product id, product bill id and.. the bill id is passed to my controller as a parameter.
I can use the entities from framework and find all rows with product id using
db.tbl_product.Find(product id).
But now i need to find all transactions using bill id. How do I do that??
Assuming tbl_product is a DbSet<Product> or something similar, you should be able to use LINQ to query the DbSet. To find a single item with a specific BillId property value, you would do something like this:
var product = db.tbl_product.FirstOrDefault(p => p.BillId == billId);
If there were multiple products with the same BillId, you could do the following:
var products = db.tbl_product.Where(p => p.BillId == billId);
It largely depends on the schema of the table and how you're using Entity Framework. I would highly recommend reading a book or tutorial on Entity Framework. There are lots of them out there, for example: Entity Framework Tutorial.

Mongo Schema Design

I'm pretty new to Mongo. Just started a project using Mongodb as the database.
I'm not sure how should i design the following use-case to a document base database.
User-Case
1. Vendor/Distributor has a list of product on our system.
2. There's a standard price list of each product for any customers.
3. Vendor/Distributor also has customize price list of each of the product for each customer.
eg. CustA have a productA at different pricing from the standard and it's only available to him.
4. Some of the Product are only available through customize price, and I match those product with attribute public = false.
How should i work this out in document base database?
Current design i have is.
1. [Product Document] with embedded document of standard price list.
2. [Product_Price Document] with oneToMany link [Product Document] and oneToMany to [Customer Document]
3. [Customer Document].
With this Model, I'm facing problem with querying by paging.
Example I query the first 30 Product sorted by name. Then query [Product_Price Document] with the 30 ProductId that match, so that I have those customize price for that customer who login.
The problems come where by I couldn't query item that are customize to the user that is not available for everyone.
Is there a better way or design the schema or what should i do with the query?
I'm using PHP, Doctrine2, Symfony2
When you query the Product_Price_Document query it using both ProductID and current CustomerID. Or am I missing something?
Here's how I would structure it.
Have two collections:
- Products
- Vendors
Your products table would have the list of all your products and their standard price. Your vendors page would have an array of product ID's along with an override price in the case that they have a different price for that particular product.
If you are also tracking customers then you could make that a collection too and have a belongs to relationship almost to the vendors.
so in short:
collection.vendor:
{"name":'foo',"products":[{"_id":mongoId,"priceOveride":15.50},..]}
collection.products:
{"name":"bar","price":15.40}
Excellent resource for reading a bit more into the relationships which you can use:
Learn Mongo Interactively

Entity Framework many-to-many question

Please help an EF n00b design his database.
I have several companies that produce several products, so there's a many-to-many relationship between companies and products. I have an intermediate table, Company_Product, that relates them.
Each company/product combination has a unique SKU. For example Acme widgets have SKU 123, but Omega widgets have SKU 456. I added the SKU as a field in the Company_Product intermediate table.
EF generated a model with a 1:* relationship between the company and Company_Product tables, and a 1:* relationship between the product and Company_Product tables. I really want a : relationship between company and product. But, most importantly, there's no way to access the SKU directly from the model.
Do I need to put the SKU in its own table and write a join, or is there a better way?
I just tested this in a new VS2010 project (EFv4) to be sure, and here's what I found:
When your associative table in the middle (Company_Product) has ONLY the 2 foreign keys to the other tables (CompanyID and ProductID), then adding all 3 tables to the designer ends up modeling the many to many relationship. It doesn't even generate a class for the Company_Product table. Each Company has a Products collection, and each Product has a Companies collection.
However, if your associative table (Company_Product) has other fields (such as SKU, it's own Primary Key, or other descriptive fields like dates, descriptions, etc), then the EF modeler will create a separate class, and it does what you've already seen.
Having the class in the middle with 1:* relationships out to Company and Product is not a bad thing, and you can still get the data you want with some easy queries.
// Get all products for Company with ID = 1
var q =
from compProd in context.Company_Product
where compProd.CompanyID == 1
select compProd.Product;
True, it's not as easy to just navigate the relationships of the model, when you already have your entity objects loaded, for instance, but that's what a data layer is for. Encapsulate the queries that get the data you want. If you really want to get rid of that middle Company_Product class, and have the many-to-many directly represented in the class model, then you'll have to strip down the Company_Product table to contain only the 2 foreign keys, and get rid of the SKU.
Actually, I shouldn't say you HAVE to do that...you might be able to do some edits in the designer and set it up this way anyway. I'll give it a try and report back.
UPDATE
Keeping the SKU in the Company_Product table (meaning my EF model had 3 classes, not 2; it created the Company_Payload class, with a 1:* to the other 2 tables), I tried to add an association directly between Company and Product. The steps I followed were:
Right click on the Company class in the designer
Add > Association
Set "End" on the left to be Company (it should be already)
Set "End" on the right to Product
Change both multiplicities to "* (Many)"
The navigation properties should be named "Products" and "Companies"
Hit OK.
Right Click on the association in the model > click "Table Mapping"
Under "Add a table or view" select "Company_Product"
Map Company -> ID (on left) to CompanyID (on right)
Map Product -> ID (on left) to ProductID (on right)
But, it doesn't work. It gives this error:
Error 3025: Problem in mapping fragments starting at line 175:Must specify mapping for all key properties (Company_Product.SKU) of table Company_Product.
So that particular association is invalid, because it uses Company_Product as the table, but doesn't map the SKU field to anything.
Also, while I was researching this, I came across this "Best Practice" tidbit from the book Entity Framework 4.0 Recipies (note that for an association table with extra fields, besides to 2 FKs, they refer to the extra fields as the "payload". In your case, SKU is the payload in Company_Product).
Best Practice
Unfortunately, a project
that starts out with several,
payload-free, many-to-many
relationships often ends up with
several, payload-rich, many-to-many
relationships. Refactoring a model,
especially late in the development
cycle, to accommodate payloads in the
many-to-many relationships can be
tedious. Not only are additional
entities introduced, but the queries
and navigation patterns through the
relationships change as well. Some
developers argue that every
many-to-many relationship should start
off with some payload, typically a
synthetic key, so the inevitable
addition of more payload has
significantly less impact on the
project.
So here's the best practice.
If you have a payload-free,
many-to-many relationship and you
think there is some chance that it may
change over time to include a payload,
start with an extra identity column in
the link table. When you import the
tables into your model, you will get
two one-to-many relationships, which
means the code you write and the model
you have will be ready for any number
of additional payload columns that
come along as the project matures. The
cost of an additional integer identity
column is usually a pretty small price
to pay to keep the model more
flexible.
(From Chapter 2. Entity Data Modeling Fundamentals, 2.4. Modeling a Many-to-Many Relationship with a Payload)
Sounds like good advice. Especially since you already have a payload (SKU).
I would just like to add the following to Samuel's answer:
If you want to directly query from one side of a many-to-many relationship (with payload) to the other, you can use the following code (using the same example):
Company c = context.Companies.First();
IQueryable<Product> products = c.Company_Products.Select(cp => cp.Product);
The products variable would then be all Product records associated with the Company c record. If you would like to include the SKU for each of the products, you could use an anonymous class like so:
var productsWithSKU = c.Company_Products.Select(cp => new {
ProductID = cp.Product.ID,
Name = cp.Product.Name,
Price = cp.Product.Price,
SKU = cp.SKU
});
foreach (var
You can encapsulate the first query in a read-only property for simplicity like so:
public partial class Company
{
public property IQueryable<Product> Products
{
get { return Company_Products.Select(cp => cp.Product); }
}
}
You can't do that with the query that includes the SKU because you can't return anonymous types. You would have to have a definite class, which would typically be done by either adding a non-mapped property to the Product class or creating another class that inherits from Product that would add an SKU property. If you use an inherited class though, you will not be able to make changes to it and have it managed by EF - it would only be useful for display purposes.
Cheers. :)