You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

472 lines
14 KiB

/**
* Common.hx : Shared entities between server and client
*/
@:keep
typedef OrderSimple = {
products: Array<{
product:ProductInfo,
quantity:Int
}>,
total:Float
}
//A temporary order, waiting for being paid and definitely recorded.
@:keep
typedef OrderInSession = {
products:Array <{
productId:Int,
quantity:Float,
#if !js
?product:db.Product,
?distributionId:Int,
#end
} > ,
?userId:Int,
total:Float, //price to pay
?paymentOp:Int, //payment operation ID
}
@:keep
typedef ProductInfo = {
id : Int,
name : String,
ref : Null<String>,
image : Null<String>,
contractId : Int,
price : Float,
vat : Null<Float>, //VAT rate
vatValue : Null<Float>, //amount of VAT included in the price
contractTax : Null<Float>, //pourcentage de commission défini dans le contrat
contractTaxName : Null<String>, //label pour la commission : ex: "frais divers"
desc : Null<String>,
categories : Null<Array<Int>>, //used in old shop
subcategories : Null<Array<Int>>, //used in new shop
orderable : Bool, //can be currently ordered
stock: Null<Float>, //available stock
hasFloatQt : Bool,
qt:Null<Float>,
unitType:Null<Unit>,
organic:Bool,
variablePrice:Bool,
wholesale:Bool,
active:Bool,
?distributionId:Null<Int>, //in the context of a distrib
}
@:keep
typedef ProductWithQuantity = {
product: ProductInfo,
quantity: Int
}
enum Unit{
Piece;
Kilogram;
Gram;
Litre;
Centilitre;
}
typedef CategoryInfo = {
id:Int,
name:String,
?subcategories:Array<CategoryInfo>
}
/**
* datas used with the "tagger" ajax class
*/
@:keep
typedef TaggerInfos = {
products:Array<{product:ProductInfo,categories:Array<Int>}>,//tagged products
categories : Array<{id:Int,categoryGroupName:String,color:String,tags:Array<{id:Int,name:String}>}>, //groupe de categories + tags
}
/**
* Links in navbars for plugins
*/
typedef Link = {
id:String,
link:String,
name:String,
?icon:String,
}
typedef Block = {
id:String,
title:String,
?icon:String,
html:String
}
typedef UserOrder = {
id:Int,
userId:Int,
userName:String,
?userEmail : String,
?userId2:Int,
?userName2:String,
?userEmail2:String,
//deprecated
?productId:Int,
?productRef:String,
?productName:String,
?productPrice:Float,
?productImage:String,
?productQt:Float,
?productUnit:Unit,
?productHasFloatQt:Bool,
?productHasVariablePrice:Bool,
//new way
?product:ProductInfo,
quantity:Float,
smartQt:String,
subTotal:Float,
fees:Null<Float>,
percentageName:Null<String>,
percentageValue:Null<Float>,
total:Float,
//flags
paid:Bool,
invertSharedOrder:Bool,
canceled:Bool,
canModify:Bool,
contractId:Int,
contractName:String,
}
typedef PlaceInfos = {
id:Int,
name:String,
address1:String,
address2:String,
zipCode:String,
city:String,
latitude:Float,
longitude:Float
}
typedef UserInfo = {
id:Int,
name:String,
email:String,
}
typedef GroupOnMap = {
id:Int,
name:String,
image:String,
place:PlaceInfos,
}
enum OrderFlags {
InvertSharedOrder; //invert order when there is a shared/alternated order
//Canceled; //flag for cancelled orders, qt should always be 0
}
typedef OrderByProduct = {
quantity:Float,
smartQt:String,
pid:Int,
pname:String,
ref:String,
priceHT:Float,
priceTTC:Float,
vat:Float,
totalHT:Float,
totalTTC:Float,
weightOrVolume:String,
};
typedef OrderByEndDate = {date: String,contracts: Array<String>};
/**
Event enum used for plugins.
As in most CMS event systems,
the events (or "triggers") can be caught by plugins
to perform an action or modifiy data carried by the event.
**/
enum Event {
Page(uri:String); //a page is displayed
Nav(nav:Array<Link>, name:String, ?id:Int); //a navigation is displayed, optionnal object id if needed
Blocks(blocks:Array<Block>, name:String, ?context:Dynamic); //HTML blocks that can be displayed on a page
#if sys
SendEmail(message : sugoi.mail.Mail); //an email is sent
NewMember(user:db.User,group:db.Amap); //a new member is added to a group
NewGroup(group:db.Amap, author:db.User); //a new group is created
//Distributions
PreNewDistrib(contract:db.Contract); //when displaying the insert distribution form
NewDistrib(distrib:db.Distribution); //when a new distrinbution is created
PreEditDistrib(distrib:db.Distribution);
EditDistrib(distrib:db.Distribution);
DeleteDistrib(distrib:db.Distribution);
PreNewDistribCycle(cycle:db.DistributionCycle);
NewDistribCycle(cycle:db.DistributionCycle);
MultiDistribEvent(md:MultiDistrib);
//Products
PreNewProduct(contract:db.Contract); //when displaying the insert distribution form
NewProduct(product:db.Product); //when a new product is created
PreEditProduct(product:db.Product);
EditProduct(product:db.Product);
DeleteProduct(product:db.Product);
BatchEnableProducts(data:{pids:Array<Int>,enable:Bool});
ProductInfosEvent(p:ProductInfo,?d:db.Distribution); //when infos about a product are displayed
//Contracts
EditContract(contract:db.Contract,form:sugoi.form.Form);
DuplicateContract(contract:db.Contract);
DeleteContract(contract:db.Contract);
//crons
DailyCron;
HourlyCron;
MinutelyCron;
//orders
MakeOrder(orders:Array<db.UserContract>);
StockMove(order:{product:db.Product, move:Float}); //when a stock is modified
//payments
GetPaymentTypes(data:{types:Array<payment.Payment>});
NewOperation(op:db.Operation);
#end
}
/*
* Product Taxonomy structure
*/
typedef TxpDictionnary = {
products:Map<Int,{id:Int,name:String,category:Int,subCategory:Int}>,
categories:Map<Int,{id:Int,name:String}>,
subCategories:Map<Int,{id:Int,name:String}>,
}
/*
* Tutorials
*/
enum TutoAction {
TAPage(uri:String);
TANext;
}
enum TutoPlacement {
TPTop;
TPBottom;
TPLeft;
TPRight;
}
class TutoDatas {
public static var TUTOS;
#if js
//async
public static function get(tuto:String, callback:Dynamic->Void){
#if !test
sugoi.i18n.Locale.init(App.instance.LANG, function(t:sugoi.i18n.GetText){
App.instance.t = t;
init(t);
var tuto = TUTOS.get(tuto);
callback(tuto);
});
#end
}
#else
//sync
public static function get(tuto:String):{name:String, steps:Array<{element:String,text:String,action:TutoAction,placement:TutoPlacement}>}
{
sugoi.i18n.Locale.init(App.current.getLang());
init(sugoi.i18n.Locale.texts);
return TUTOS.get(tuto);
}
#end
static function init(t:sugoi.i18n.GetText){
TUTOS = [
"intro" => {
name:t._("Guided tour for the coordinator"),
steps:[
{
element:null,
text:t._("<p>In order to better discover Cagette.net, we propose to do a guided tour of the user interface of the software. <br/> You will then have a global overview on the different tools that are available to you.</p><p>You will be able to stop and start again this tutorial whenever you want.</p>"),
action: TANext,
placement : null
},
{
element:"ul.nav.navbar-left",
text:t._( "This part of the navigation bar is visible by all members.</br>It allows to access to the three main pages: <ul><li> The <b>home page</b> which displays orders and the delivery planning.</li><li> On the <b>My account</b> page, you can update your personal information and check your orders history</li><li> On the <b>Farmers</b> page, you can see all farmers and coordinators of the group</ul>"),
action: TANext,
placement : TPBottom
},
{
element:"ul.nav.navbar-right",
text:t._("This part is <b>for coordinators only.</b>Here you will be able to manage the register of members, orders, products, etc.<br/><p>Now click on the <b>Members</b> section</p>"),
action: TAPage("/member"),
placement : TPBottom
},{
element:".article .table td:first",
text:t._("The purpose of this section is to administrate the list of your members.<br/>Every time that you register a new membrer, an account will be created for him/her. Now the member can join you at Cagette.net and order or consult the planning of the deliveries.<p>Now click on a <b>member</b> in the list</p>"),
action: TAPage("/member/view/*"),
placement : TPRight
},{
element:".article:first",
text:t._("This is the page of a member. Here you can : <ul><li>see and change their contact details</li><li>manage the membership fee of your group</li><li>see a summary of their orders</li></ul>"),
action: TANext,
placement : TPRight
},{
element:"ul.nav #contractadmin",
text:t._("Now let's have a look at the <b>contracts</b> section which is very important for coordinators."),
action: TAPage("/contractAdmin"),
placement : TPBottom
},{
element:"#contracts",
text:t._("Here you find the list of <b>contracts</b>.They inculde a start date, a end date, and represent your relationship with a farmer. <br/><p>Here you can manage :<ul><li>the list of products of this farmer</li><li>the orders of members for this farmer</li><li>and plan the delivery schedule</li></ul></p>"),
action: TANext,
placement : TPBottom
},{
element:"#places",
text:t._("Here you can manage the list of <b>delivery places</b>.<br/>Don't forget to key-in the complete address as a map will be displayed based on this address"),
action: TANext,
placement : TPTop
},{
element:"#contracts table .btn:first",
text:t._("Let's look closer at how to manage a contract. <b>Click on this button</b>"),
action: TAPage("/contractAdmin/view/*"),
placement : TPBottom
},{
element:".table.table-bordered:first",
text:t._("Here is a summary of the contract.<br/>There are two types of contracts:<ul><li>Constant contracts: the member commits on buying the same products during the whole duration of the contract</li><li>Variable contracts: the member can choose what he buys for each delivery.</li></ul>"),
action: TANext,
placement : TPRight
},{
element:"#subnav #products",
text:t._("Let's see now the page <b>Products</b>"),
action : TAPage("/contractAdmin/products/*"),
placement:TPRight
},{
element:".article .table",
text:t._("On this page, you can manage the list of products offered by this supplier.<br/>Define at least the name and the price of products. It is also possible to add a description and a picture."),
action: TANext,
placement : TPTop
},{
element:"#subnav #deliveries",
text:t._("Let's see the <b>deliveries</b> page"),
action : TAPage("/contractAdmin/distributions/*"),
placement:TPRight
},{
element:".article .table",
text:t._("Here we can manage the list of deliveries for this supplier.<br/>In the software, a delivery has a date, a start time, and an end time. The location of the delivery must also be defined, by using the list that we have already seen."),
action: TANext,
placement : TPLeft
},{
element:"#subnav #orders",
text:t._("Let's see now the <b>Orders</b> page"),
action : TAPage("/contractAdmin/orders/*"), //can fail if the contract is variable because the uri is different
placement:TPRight
},{
element:".article .table",
text:t._("Here we can manage the list of orders for this supplier.<br/>If you choose to \"open orders\" to members, they will be able to make their orders online themselves.<br/>This page will centralize automatically the orders for this supplier. Otherwise, as a coordinator, you will be able to enter orders on behalf of a member."),
action: TANext,
placement : TPLeft
},{
element:"ul.nav #messages",
text:t._("<p>We have seen the main features related to contracts.</p><p>Let's see the <b>messaging</b> section.</p>"),
action: TAPage("/messages"),
placement : TPBottom
},{
element:null,
text:t._("<p>The messaging section allows you to send e-mails to different lists of members. It is not necessary anymore to maintain a lot of lists of e-mails depending on contracts, as all these lists are automatically generated.</p> <p>E-mails are sent with your e-mail address as sender, so you will receive answers in your own mailbox.</p>"),
action: TANext,
placement : null
},{
element:"ul.nav #amapadmin",
text:t._("Click here now on this page"),
action : TAPage("/amapadmin"),
placement : TPBottom,
},{
element:"#subnav",
text:t._("<p>In this last page, you can configure everything that is related to your group.</p><p>The page <b>Access rights</b> is important as it is where you can define other coordinators among members. They will then be able to manage one or many contracts, send emails, etc.</p>"),
action:TANext,
placement : TPBottom
},{
element:"#footer",
text:t._("<p>This is the last step of this tutorial. I hope that it gave you a good overview of this software.<br/>To go further, do not hesitate to look at the <b>documentation</b>. The link is always available at the bottom of the screen.</p>"),
action:TANext,
placement : TPBottom
}
]
},
];
}
}
/**
* Order Reports
*/
enum OrdersReportGroupOption{
ByMember;
ByProduct;
}
enum OrdersReportFormatOption{
Table;
Csv;
PrintableList; //list de distrib ?
}
//Report Options : should be usable in an URL, an API call...
typedef OrdersReportOptions = {
//time scope
startDate:Date,
endDate:Date,
//formatting
?groupBy:OrdersReportGroupOption, //group order by...
?format:OrdersReportFormatOption, //table , csv ?
//filters :
?groups:Array<Int>,
?contracts:Array<Int>, //which contracts
?distributions:Array<Int>,
}