For details about Mantle see its page on moqui.org:
http://www.moqui.org/mantle.html
There is an overview of Mantle Business Artifacts in the Making Apps with Moqui book. Download the PDF here:
Mantle Universal Service Library
Home Page: http://www.moqui.org/mantle.html
License: Other
For details about Mantle see its page on moqui.org:
http://www.moqui.org/mantle.html
There is an overview of Mantle Business Artifacts in the Making Apps with Moqui book. Download the PDF here:
Recurring orders are defined by 2 conditions: status=OrderApproved, and the recurCronExpression not being null. These 2 conditions can be configured inside the POPC backend order screen.
Subscription products(type=PtDigital, then a proper ProductSubscriptionResource), are processed by the mentioned service. This happens automatically when the order status changes to OrderApproved. However, this processing should not occur for recurring orders; otherwise, it will auto-complete, and that is certainly not what is expected.
I have a pull request for this.
Based on demo data.
I call servcie mantle.product.AssetServices.receive#Asset with folloing input
assetId:DEMO_1_1A
productId:DEMO_1_1
facilityId:MY_NEW_FACILITY
quantity:7
I think the expected result should be a new asset is created. But the current result is only the QOH and ATP of existing asset are updated in db. It seems the asset is received to facility ORG_ZIZI_RETAIL_WH rather than MY_NEW_FACILITY. I don't think this is correct
I am not sure if I am correct.
Messages exceeding 255 characters cannot be localized as of restrictions in database and L10nFacadeImpl.localize() implementation.
Service OrderInfoServices.check#OrderPreApprove has one message that exceed 255 characters, currently on line 612 with 276 characters:
<iterate list="nearItemList" entry="nearItem"><script>approveWarnings.add(ec.resource.expand( 'Found similar order ${nearOrder.orderId}:${nearOrder.orderPartSeqId} placed ${ec.l10n.format(nearOrder.placedDate, null)} (${ec.l10n.format(diffHours, "0.0")}h ${isFuture ? "after" : "before"}) with ${ec.l10n.format(nearItem.quantity, "0.##")} of product ${nearItem.productId}', null))</script></iterate>
<service verb="restore" noun="TenantAccess">
<implements service="mantle.product.SubscriptionServices.revoke#SubscriptionResourceAccess"/>
It's luck that all those interfaces have the same definitions.
Re. mantle.work.WorkEffortServices.clone#WorkEffort, it cannot create correct WorkEffortAssoc for new cloned milesones and tasks, the new cloned milestones are associated to the tasks in based project.
Hope that makes sense.
debitCreditFlag for credit memo is incorrect.
Example:
https://docs.oracle.com/cd/A60725_05/html/comnls/us/ar/act4trx.htm
When call service mantle.party.PartyServices.find#Party
, a warning message occurred
Error adding authz entity filter condition: org.moqui.entity.EntityException: Tried to filter on field toPartyId which is not included in view-entity mantle.party.FindPartyView
In Mantle EntityFilter setup:
<filters entityFilterId="MANTLE_USER_ORG_8" entityName="mantle.party.PartyRelationship" filterMap="[_join:'or', _list:[[toPartyId:filterOrgIds, _comp:'in'], [relationshipTypeEnumId:(filterOrgIds ? 'PrtEmployee' : null), _comp:'!=']]]"/>
If I understood correctly, to inherit pre-defined filter setup on PartyRelationship, we should add alias toPartyId
into view-entity definition FindPartyView and use exact name for relationshipTypeEnumId.
On the screens
SimpleScreens/screen/BasicHandheld/Warehouse/dashboard.xml
SimpleScreens/screen/BasicHandheld/Warehouse/Asset/SelectAsset.xml
SimpleScreens/screen/SimpleScreens/Asset/Asset/SelectAsset.xml
searching an Asset ID go in error:
{serviceNamePretty=Mantle Product Services Find Product By ID Value, form=null, field=idValue, fieldPretty=ID Value, serviceName=mantle.product.ProductServices.find#ProductByIdValue, formPretty=, message=Field cannot be empty}
Found error(s) when validating input parameters for service mantle.product.ProductServices.find#ProductByIdValue, so not running service. Errors: Field cannot be empty(for field ID Value of service Mantle Product Services Find Product By ID Value
; the artifact stack is:
[name:'mantle.facility.FacilityServices.get#ScannedIdGeneral', type:'AT_SERVICE', action:'AUTHZA_VIEW', required: true, granted:true, user:'EX_JOHN_DOE', authz:'AUTHZT_ALWAYS', authAction:'AUTHZA_ALL', inheritable:true, runningTime:0]
[name:'component://SimpleScreens/screen/BasicHandheld/Warehouse/dashboard.xml/checkScanInput', type:'AT_XML_SCREEN_TRANS', action:'AUTHZA_VIEW', required: true, granted:true, user:'EX_JOHN_DOE', authz:'AUTHZT_ALWAYS', authAction:'AUTHZA_ALL', inheritable:true, runningTime:0]
[name:'component://SimpleScreens/screen/BasicHandheld/Warehouse/dashboard.xml', type:'AT_XML_SCREEN', action:'AUTHZA_VIEW', required: false, granted:true, user:'EX_JOHN_DOE', authz:'AUTHZT_ALWAYS', authAction:'AUTHZA_ALL', inheritable:true, runningTime:0]
[name:'component://SimpleScreens/screen/BasicHandheld/Warehouse.xml', type:'AT_XML_SCREEN', action:'AUTHZA_VIEW', required: false, granted:true, user:'EX_JOHN_DOE', authz:'AUTHZT_ALWAYS', authAction:'AUTHZA_ALL', inheritable:true, runningTime:0]
[name:'component://webroot/screen/webroot/apps.xml', type:'AT_XML_SCREEN', action:'AUTHZA_VIEW', required: false, granted:false, user:'null', authz:'null', authAction:'null', inheritable:false, runningTime:0]
[name:'component://webroot/screen/webroot.xml', type:'AT_XML_SCREEN', action:'AUTHZA_VIEW', required: false, granted:false, user:'null', authz:'null', authAction:'null', inheritable:false, runningTime:0]
Should be when transition checkScanInput call mantle.facility.FacilityServices.get#ScannedIdGeneral that call mantle.product.ProductServices.find#ProductByIdValue.
In reference to another ticket and also the fix that was done to the fulfill#ProductSubscriptionResource
service, a new problem emerged that we noticed in fullfill#OrderPartSubscriptions
in that the dates are now incorrect
I believe the solution is to apply this PR which essentially avoids querying expired subscriptions and also removes an incorrect fromDate being passed from the ProductSubscriptionResource entity for some strange reason
I got this issue while trying builtin swagger UI to discover REST service in Moqui: http://localhost:8080/rest/service.swagger/mantle.json
No field found for path parameter partyId in entity mantle.party.contact.ContactMechPurpose
The same issue occured with the Moqui demo site at: https://demo.moqui.org/rest/service.swagger/mantle.json
Hi David,
When you send a PUT
request to the API to update product you expect all of its data in response (similar to what you receive back on GET
), don't you?
Our request is:
curl -X PUT -u john.doe:moqui -H 'Content-Type: application/json' -d '{"pseudoId":"100002","productName":"Updated Product","prices":[{...}],"parties":[{...},{...}],"contents":[{...},{...}],"status":{...}}' https://example.moqui.org/rest/m1/products/100002
Response from API:
{
"oldStatusId": "PrvwPending",
"parties": [
{
},
{
},
{
}
],
"statusChanged": false,
"productId": "100002",
"prices": {
"productPriceId": "100152"
},
"contents": [
{
"productContentId": "100000"
},
{
"productContentId": "100001"
}
]
}
There are two problems with that response:
"parties"
is an array of empty hashes - hashes should include at least all of the primary keys"prices"
is a hash instead of array of hashes (Product has many
Prices) - happens only when product has one priceThanks!
Bart
The rest of the lines in this method use nowTimestamp, which is a local variable. Calling ec.user.nowTimestamp creates a new value each time. This was changed when the MR we submitted was slightly refactored.
I'm confused about the meaning of Product.amountFixed
vs OrderItem.selectedAmount
:
For products with fixed amounts such as gift certificate amounts, rope lengths, etc.
From these explanation, I understood that Product.amountFixed
andOrderItem.selectedAmount
have the same meaning.
However, in OrderServices.create#OrderItem, there's a comment about difference between Product.amountFixed
and OrderItem.selectedAmount
( mantle-usl )
Do NOT do this: Product.amountFixed means inherent amount of item included in quantity, not a selected amount!
This comment is already moved out in current version, but selectedAmount is not set from amountFixed too, . So I wonder if we still need to capture Product.amountFixed
or not, and do we need to add additional field to set selectedAmount
in product definition?
Creating variant products, in the id is not possible to sort the abbreviations of the selectable product features applied directly to the virtual product or using a product feature group associated to a category where the virtual product belong to.
Seems that the iteration that build the id follows a sorting using the enumId of the Product Feature Type of the product features applied.
Is there a way to order the abbreviation list that build the variant product id?
Thanks
This exception occurs when creating Event from AssetCalendar screen in PopCommerce Admin module, in which any duration related field left blank:
Error running service [mantle.work.WorkEffortServices.get#WorkEffortStartEnd] (message): Field cannot be empty (for field amount of service org.m
oqui.impl.BasicServices.convert#Uom
Although the source of problem is the Event ifself, I think it's better if the service mantle.work.WorkEffortServices.get#WorkEffortStartEnd should do checking before calling convert.
I've just reset my cluster, and it loaded a copy of sanitized production data. At startup, this created an order, which then had 2800(or so, some super large number) of OrderItemWorkEffort. The following code then is running, and running, and running, doing the same delete call into elasticsearch.
It would seem to be more efficient to just do 1 delete call.
19:26:50.721 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:50.824 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:50.933 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:51.045 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:51.711 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:51.868 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:52.008 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:52.120 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:52.367 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:52.517 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:52.676 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:52.968 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.059 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:53.187 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.277 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:53.360 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.433 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:53.507 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.578 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:53.658 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.766 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:53.882 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:53.993 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:54.128 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:54.253 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02 19:26:54.407 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_sales_order_item with ID 101275::02 19:26:54.501 WARN oquiWorker-9 o.moqui.i.c.ElasticFacadeImpl In delete document not found in index mantle_inventory_order_item with ID 101275::02
When I am trying to use the REST API to access different mantle services I keep getting 403 errors, I dont think this is meant to happen for admin users as I spotted https://github.com/moqui/mantle-usl/blob/master/data/MantleSetupData.xml#L20 where the admin group is authorised?
$ curl -X GET -u john.doe:moqui http://localhost:8080/rest/e1/parties
<html><head><title>Error 403</title></head><body bgcolor="#ffffff"><h1>Status Code: 403</h1>Exception: User [john.doe] is not authorized for View on Entity [mantle.party.Party], here is the current artifact stack:
[name:'component://webroot/screen/webroot/rest.xml/e1',type:'AT_XML_SCREEN_TRANS',action:'AUTHZA_VIEW',user:'null',authz:'null',authAction:'null',inheritable:false,runningTime:0]
[name:'component://webroot/screen/webroot/rest.xml',type:'AT_XML_SCREEN',action:'AUTHZA_VIEW',user:'null',authz:'null',authAction:'null',inheritable:false,runningTime:0]
[name:'component://webroot/screen/webroot.xml',type:'AT_XML_SCREEN',action:'AUTHZA_VIEW',user:'null',authz:'null',authAction:'null',inheritable:false,runningTime:0]<br>Stacktrace: <pre>(none)
</pre><br><hr size="1" width="90%"><i>Generated by Winstone Servlet Engine v1.7.0 at Wed Feb 17 15:27:43 CST 2016</i></body></html>
Am I missing something? On a separate note I also suppose that errors for the json api should not spit back html?
Thanks
Sam
To Reproduce
You will get the error “Field cannot be empty (for field contactMechId)”.
It is caused by the parameter contactMechId is changed to required in update#PartyContactOther in ce438c4
In fulfill#ProductSubscriptionResource, there is a comment determine fromDate (either last Subscription.thruDate if in future, or nowTimestamp
; however, that 'if in future' bit is never actually tested for in the following logic.
What has occurred, is that my account in our system had an activate subscription that ran up to August 1st. But then, we implemented a change to our database process, and now local development systems no longer have correct production credit card processor settings. So, the nightly process that renews the monthly subscription failed(this is actually fine), so as of right now(August 18th), I do not have an active subscription.
I then attempted to create a new subscription(using prorated days, 14, to round out to the end of the month). The linked service above then attempted to extend the subscription from August 1, through August 15th, instead of $now to August 31.
I've tried the service get#InventoryProjectedInfo and find that some sum aggregation fields have no data, i.e all reservations sub fields. Related data documents already exists (checked using System's DataDocument search)
Trying use the full field path like it:
aggregations: [
orderQuantitySum: [sum: [field:'orderQuantity']],
quantityReservedSum: [sum: [field:'reservations.quantityReserved']],
quantityNotAvailableSum: [sum: [field:'reservations.quantityNotAvailable']],
quantityNotIssuedSum: [sum: [field:'reservations.quantityNotIssued']]
]
then I got the output for that fields but also an exception from ElasticSearch because of not numeric data type.
I wonder if this service is not fully implemented yet, or there's something wrong with Elastic.
An exception is thrown when running this service:
java.lang.NullPointerException: Cannot get property 'contactMechId' on null object
at mantle_party_ContactServices_get_PartyContactInfo.run(mantle_party_ContactServices_get_PartyContactInfo:101) ~[script:?]
I found that the problematic code is L125
Maybe the correct code should be:
<set field="emailContactMechId" from="postalAddress.emailContactMechId"/>
I think it should be returnItemSeqId
I've tested the mantle-usl Testsuite and failed at 2 testcases of OrderProcureToPayBasicFlow: "depreciate Fixed Assets", "sell Depreciated Asset Loss".
Looking to the build result in Travis of upstream repo, all testcases passed.
After debugging into the related services, I find that:
mantle.ledger.AssetAutoPostServices.calculateAndPost#AllFixedAssetDepreciations
with blank transactionDate
<set field="transactionDate" from="ec.l10n.parseTimestamp((timePeriod.thruDate as String) + ' 12:00:00', '')"/>
timePeriod.thruDate has Date type with is convert to String as '2016-08-31'. Because the TimeZone of my local PC is UTC+7, the transactionDate will be the nextDate ('2016-09-01 00:00:00')
As a result, in later service, Moqui can't find the respected timePeriod, which cause the next processing failed.
Sugguestion: if we want to default the transactionDate as the last date of this period, shouldn't convert timePeriod.thruDate into Timestamp using Locale/Timezone. Only copy the Date portion, while let the Time portion at a specific time, i.e 12:00:00
To reproduce
You will get the error message below.
Error finding list of WorkEffortContent by (workEffortId = HM (java.lang.String)) AND (((fromDate = null) OR (fromDate <= 2017-05-24 14:21:20.372 (java.sql.Timestamp))) AND ((thruDate = null) OR (thruDate > 2017-05-24 14:21:20.372 (java.sql.Timestamp))))
Not sure if we should remove <date-filter/> from <entity-find/> or add fromDate and thruDate in WorkEffortContent entity definition.
The first listed service scans the system for any order that is configured to be recurring. Then, in a loop, it calls the second service, which then does the actual work. The first service runs being a schedule job, and doesn't require a logged in user. The second service, doesn't follow the same pattern.
I've got a patch for this forthcoming.
Hi David,
If you are trying to PUT a single product price, then the returned JSON sends back an object rather than the array that we would expect from where there is only one price to be returned.
$ curl -X PUT -u john.doe:moqui -H 'Content-Type: application/json' -d '{"productId":"100052","pseudoId":"100052","productName":"New Product ","description":null,"lastUpdatedStamp":"2016-03-22T08:17:05.000Z","prices":[{"productPriceId":"100101","price":125,"fromDate":"2016-03-21T06:51:00.000Z","lastUpdatedStamp":"2016-03-22T08:17:05.000Z","product":"100052"}]}' 'https://moqui.example.com/rest/m1/products/100052'
{
"productId": "100052",
"prices": {
"productPriceId": "100101"
}
}
What is expected would be an array e.g.
{
"productId": "100052",
"prices": [
{
"productPriceId": "100101"
}
]
}
<set field="curRevision" from="ec.l10n.parseNumber(existingOrder.externalRevision ?: 1, '')"/>
<set field="newRevision" from="ec.l10n.parseNumber(header.externalRevision ?: 1, '')"/>
method parseNumber
accepts param as String, so this code should be
<set field="curRevision" from="ec.l10n.parseNumber(existingOrder.externalRevision ?: '1', '')"/>
<set field="newRevision" from="ec.l10n.parseNumber(header.externalRevision ?: '1', '')"/>
<entity-find entity-name="mantle.order.OrderHeaderAndPart" list="existingOrderList">
<econditions combine="or">
<econdition field-name="externalId" from="header.externalId"/>
<econdition field-name="otherPartyOrderId" from="header.otherPartyOrderId"/>
</econditions>
<econdition field-name="customerPartyId" from="header.customerPartyId"/>
</entity-find>
Sample data:
When I call this service with input-params map = [externalId: "100001", customerPartyId: "CustJqp"], I expected to get existing orderId = "100001". However, the result is one with orderId = "100000".
I think that this code snippet should check matching for externalId firstly, else will check if otherPartyOrderId matched (and not null).
I wonder if my test case is not relevant, or I misunderstand how this service works.
<?xml version="1.0" encoding="utf-8"?><ErrorResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Error</resultCode><message><code>E00003</code><text>The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:amount' element is invalid - The value &#39;0&#39; is invalid according to its datatype 'Decimal' - The MinInclusive constraint failed.</text></message></messages></ErrorResponse>
We create an order, attach a payment method, add products with quantities. Then, a promo rule applies that discounts certain products 100%. If the order only contains those discounted products, then the cost of the order ends up being totally 0. Then the CimPayment service(s) send this $0.00 charge over to Authorize.Net, which gives back an error.
InvoiceSummary view-entity is missing a default value of 1 (for quantity) in calculation of grandTotal (= IITM.quantity * IITM.amount). Returns Null value.
default-value="1" seems to be a good fit
Line 79 in https://github.com/moqui/mantle-usl/blob/master/entity/AccountingAccountViewEntities.xml.
See the attached single-line patch. Basically, I got an exception about could not find constructor for ArrayList(String), because "orderItemSeqId" was being set as the list to filter.
With the attached patch, I get an auto-completed order with a valid Subscription row in the database.
==
diff --git a/service/mantle/order/OrderServices.xml b/service/mantle/order/OrderServices.xml
index b52a924..307da4b 100644
--- a/service/mantle/order/OrderServices.xml
+++ b/service/mantle/order/OrderServices.xml
@@ -1340,7 +1340,7 @@ General Order Placement and eCommerce Usage
list="productSubscriptionResourceList" cache="true">
<econdition field-name="productId" from="product.productId"/></entity-find>
<iterate list="productSubscriptionResourceList" entry="productSubscriptionResource">
- <filter-map-list list="orderItemSeqId" to-list="currentSubscriptionList">
+ <filter-map-list list="orderSubscriptionList" to-list="currentSubscriptionList">
<field-map field-name="orderItemSeqId" from="orderItem.orderItemSeqId"/>
<field-map field-name="subscriptionResourceId" from="productSubscriptionResource.subscriptionResourceId"/>
</filter-map-list>
==
Changing the estimatedStartDate of the project I get the warning if any date is null:
"Project's new start date puts one or more tasks out of date range."
The problems are in the file ProjectServices.xml at rows 136 and 148. Possible solutions:
136:
148:
The error details is below.
Error in field expression [ec.user.userAccount.partyId] from [null]
Cannot get property 'partyId' on null object
I think we should change
<parameter name="enteredByPartyId" default="ec.user.userAccount.partyId"/>
to
<parameter name="enteredByPartyId" default="ec.user.userAccount?.partyId"/>
in OrderServices.xml
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.