Merge branch 'vnext' of github.com:pazof/yavsc into vnext

This commit is contained in:
2017-02-22 15:15:19 +01:00
18 changed files with 178 additions and 101 deletions

View File

@ -9,6 +9,7 @@ using Android.Gms.Gcm.Iid;
using Android.OS;
using Android;
using ZicMoove.Settings;
using System.Linq;
namespace ZicMoove.Droid
{
@ -101,12 +102,14 @@ namespace ZicMoove.Droid
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/global", null);
if (MainSettings.CurrentUser.Roles.Contains("Performer"))
// TODO add activity codes in the bundle
pubSub.Subscribe(token, "/topics/jobs", null);
// TODO if a Activity is specified,
// and general annonces in this activity are accepted:
//
// pubSub.Subscribe(token, "/topics/jobs/"+ActivityCode, null);
}
}
}
}

View File

@ -334,7 +334,7 @@ namespace ZicMoove
public static Task<bool> DisplayAlert(string title, string message, string yes = "OK", string no = null)
{
var currentPage = ((NavigationPage)Current.MainPage).CurrentPage;
var currentPage = Navigation.NavigationStack.Last();
if (no == null)
{
return currentPage.DisplayAlert(title, message, yes).ContinueWith(task => true);

View File

@ -10,6 +10,7 @@ namespace ZicMoove.Data
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
public class EstimateEntity : RemoteEntity<Estimate, long>
{
@ -17,18 +18,15 @@ namespace ZicMoove.Data
{
}
public async void SignAsProvider(Estimate estimate, Stream stream)
public async Task SignAsProvider(Estimate estimate, Stream stream)
{
if (estimate.Id == 0)
{
var ok = await this.Create(estimate);
if (!ok)
{
await App.DisplayAlert("Erreur d'accès au serveur", "Echec de l'envoi de l'estimation");
return;
}
this.Add(estimate);
if (!await this.Create(estimate))
{
await App.DisplayAlert("Erreur d'accès au serveur", "Echec de l'envoi de l'estimation");
}
}
using (HttpClient client = UserHelpers.CreateJsonClient())
{
@ -40,24 +38,29 @@ namespace ZicMoove.Data
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
content.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{filename}\"");
requestContent.Add(content, "file", filename);
using (var response = await client.PostAsync(
Constants.YavscApiUrl + $"/pdfestimate/prosign/{estimate.Id}", requestContent))
Constants.YavscApiUrl + $"/pdfestimate/prosign/{estimate.Id}", requestContent))
{
if (!response.IsSuccessStatusCode)
{
{
var errContent = await response.Content.ReadAsStringAsync();
throw new ApiCallFailedException($"SignAsProvider: {response.StatusCode} / {errContent}");
await App.DisplayAlert("SignAsProvider", $"{response.StatusCode}: {errContent}");
}
else
{
var json = await response.Content.ReadAsStringAsync();
JsonConvert.PopulateObject(json, estimate);
this.Add(estimate);
this.SaveEntity();
}
var json = await response.Content.ReadAsStringAsync();
JsonConvert.PopulateObject(json, estimate);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
await App.DisplayAlert("SignAsProvider", ex.Message);
}
}
this.SaveEntity();
}
// TODO Check we don't loose nothing here

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZicMoove.Model.UI
{
public enum EventSeverity
{
Info,
Warning,
Critical
}
/// <summary>
/// Encapsule un événement concernant le fonctionnement
/// de cette présente application.
/// </summary>
class AppEvent
{
public DateTime Date { get; set; }
public string Message { get; set; }
public string Component { get; set; }
public EventSeverity Severity { get; set; }
}
}

View File

@ -42,23 +42,29 @@
<ScrollView>
<StackLayout x:Name="mainStackLayout">
<Label Text="Description de la ligne de facture"
Style="{StaticResource InputLabelStyle}"></Label>
<Editor HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Text="{Binding Description, Mode=TwoWay}">
<Editor.Behaviors>
<behaviors:EditorMaxLengthValidator x:Name="descriptionLenValidator" MaxLength="12" MinLength="3" />
</Editor.Behaviors>
</Editor>
<StackLayout Orientation="Horizontal">
<Label Text="Description de la ligne de facture"
Style="{StaticResource InputLabelStyle}"></Label>
<Image x:Name="descriptionSuccessErrorImage"
Style="{Binding Source={x:Reference descriptionLenValidator}, Path=IsValid, Converter={StaticResource boolToStyleImage}}" />
<Label Text="{Binding Source={x:Reference descriptionLenValidator}, Path=Error}"
Style="{StaticResource ErrorLabelStyle}"></Label>
Style="{Binding Source={x:Reference descriptionLenValidator}, Path=IsValid, Converter={StaticResource boolToStyleImage}}" />
</StackLayout>
<Editor HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Text="{Binding Description, Mode=TwoWay}">
<Editor.Behaviors>
<behaviors:EditorMaxLengthValidator x:Name="descriptionLenValidator" MaxLength="12" MinLength="3" />
</Editor.Behaviors>
</Editor>
<Label Text="{Binding Source={x:Reference descriptionLenValidator}, Path=Error}"
Style="{StaticResource ErrorLabelStyle}"></Label>
<Label Text="Durée de la prestation"
Style="{StaticResource InputLabelStyle}">
</Label>
<StackLayout Orientation="Horizontal">
<Label Text="Durée de la prestation"
Style="{StaticResource InputLabelStyle}">
</Label>
<Image x:Name="durationSuccessErrorImage"
Style="{Binding Source={x:Reference durationValidator},
Path=IsValid,
Converter={StaticResource boolToStyleImage}}" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Entry Placeholder="Durée" Keyboard="Numeric" Style="{StaticResource BigEntry}"
Text="{Binding DurationValue, Mode=TwoWay, StringFormat='{0}'}" >
@ -71,13 +77,15 @@
Title="Unité de temps"
SelectedItem="{Binding DurationUnit, Mode=TwoWay}">
</views:EnumPicker>
<Image x:Name="durationSuccessErrorImage"
Style="{Binding Source={x:Reference durationValidator},
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Quantité facturée" Style="{StaticResource InputLabelStyle}"></Label>
<Image x:Name="countSuccessErrorImage"
Style="{Binding Source={x:Reference countValidator},
Path=IsValid,
Converter={StaticResource boolToStyleImage}}" />
</StackLayout>
<Label Text="Quantité facturée" Style="{StaticResource InputLabelStyle}"></Label>
<Entry Text="{Binding Count, Mode=TwoWay}" Placeholder="Quantité" Keyboard="Numeric"
Style="{StaticResource BigEntry}">
@ -86,15 +94,18 @@
</Entry.Behaviors>
</Entry>
<StackLayout Orientation="Horizontal">
<Image x:Name="countSuccessErrorImage"
Style="{Binding Source={x:Reference countValidator},
Path=IsValid,
Converter={StaticResource boolToStyleImage}}" />
<Label Text="{Binding Source={x:Reference countValidator}, Path=Error}"
Style="{StaticResource ErrorLabelStyle}"></Label>
</StackLayout>
<Label Text="Prix unitaire" Style="{StaticResource InputLabelStyle}"></Label>
<StackLayout Orientation="Horizontal">
<Label Text="Prix unitaire" Style="{StaticResource InputLabelStyle}">
</Label>
<Image x:Name="unitaryCostSuccessErrorImage"
Style="{Binding Source={x:Reference unitCostValidator},
Path=IsValid,
Converter={StaticResource boolToStyleImage}}" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Entry Text="{Binding UnitaryCostText, Mode=TwoWay}" Placeholder="Prix"
Keyboard="Numeric" Style="{StaticResource BigEntry}">
@ -103,15 +114,13 @@
</Entry.Behaviors>
</Entry>
<Label Text="€" Style="{StaticResource BigLabelStyle}" />
<Image x:Name="unitaryCostSuccessErrorImage"
Style="{Binding Source={x:Reference unitCostValidator},
Path=IsValid,
Converter={StaticResource boolToStyleImage}}" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Button Text="Términé"
Command="{Binding ValidateCommand}"
Clicked="OnValidateClicked"></Button>
Clicked="OnValidateClicked"
IsEnabled="{Binding ModelState.IsValid}"></Button>
<Button Text="Supprimer"
Command="{Binding RemoveCommand}"
Clicked="OnDeleteClicked"></Button>

View File

@ -4,17 +4,28 @@ using ZicMoove.ViewModels.EstimateAndBilling;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using ZicMoove.Model.Workflow;
namespace ZicMoove.Pages
{
public partial class EditBillingLinePage : ContentPage
{
public EditBillingLinePage(BillingLineViewModel model)
public void Initialize()
{
InitializeComponent();
foreach
(string du in Enum.GetNames(typeof(BillingLineViewModel.DurationUnits)))
foreach (string du in Enum.GetNames(typeof(BillingLineViewModel.DurationUnits)))
picker.Items.Add(du);
BindingContext = new BillingLineViewModel(new BillingLine());
}
public EditBillingLinePage()
{
Initialize();
}
public EditBillingLinePage(BillingLineViewModel model)
{
Initialize();
BindingContext = model;
}

View File

@ -100,7 +100,7 @@
<StackLayout Orientation="Vertical">
<Button Text="Ajouter une ligne de facture" Clicked="OnNewCommanLine"></Button>
<Label FormattedText="{Binding FormattedTotal}"/>
<Button x:Name="btnValidate" Text="Valider ce devis" Clicked="OnEstimateValidated" IsEnabled="{Binding ViewModelState.IsValid}" ></Button>
<Button x:Name="btnValidate" Text="Valider ce devis" Clicked="OnEstimateValidated" IsEnabled="{Binding ModelState.IsValid}" ></Button>
</StackLayout>
</StackLayout>
</StackLayout>

View File

@ -22,25 +22,16 @@ namespace ZicMoove.Pages
public EditEstimatePage(EditEstimateViewModel model)
{
BindingContext = model;
Model.CheckCommand = new Action<Estimate, ViewModels.Validation.ModelState>(
(e, m) =>
{
foreach (var line in model.Bill)
{
line.Check();
if (!line.ViewModelState.IsValid)
model.ViewModelState.AddError("Bill", "invalid line");
}
});
InitializeComponent();
Model.Check();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
((EditEstimateViewModel)BindingContext).PropertyChanged += EditEstimatePage_PropertyChanged;
if (Model == null) return;
Model.PropertyChanged += EditEstimatePage_PropertyChanged;
Model.Check();
}
private void EditEstimatePage_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

View File

@ -48,7 +48,7 @@ namespace ZicMoove.Pages.EstimatePages
*/
stream.Seek(0, SeekOrigin.Begin);
DataManager.Instance.Estimates.SignAsProvider(estimate, stream);
await DataManager.Instance.Estimates.SignAsProvider(estimate, stream);
DataManager.Instance.Estimates.SaveEntity();
}
IsBusy = false;

View File

@ -20,6 +20,7 @@ namespace ZicMoove.Pages.UserProfile
btnPay.Clicked += BtnPay_Clicked;
}
public UserProfilePage(UserProfileViewModel model)
{
InitializeComponent();
@ -58,9 +59,14 @@ namespace ZicMoove.Pages.UserProfile
{
using (var stream = file.GetStream())
{
var requestContent = new MultipartFormDataContent();
var content = new StreamContent(stream);
var filename = "me.jpg";
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
content.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{filename}\"");
requestContent.Add(content, "file", filename);
using (var response = await client.PostAsync(Constants.YavscApiUrl + "/setavatar", content))
using (var response = await client.PostAsync(Constants.YavscApiUrl + "/setavatar", requestContent))
{
if (response.IsSuccessStatusCode)
{

View File

@ -16,15 +16,6 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
public BillingLineViewModel(BillingLine data): base(data)
{
CheckCommand = new Action<BillingLine, ModelState>(
(l,s) => {
if (string.IsNullOrWhiteSpace(l.Description))
{
s.AddError("Description",Strings.NoDescription);
}
if (l.UnitaryCost < 0) { s.AddError("UnitaryCost", Strings.InvalidValue); }
if (l.Count < 0) { s.AddError("Count", Strings.InvalidValue); }
});
SyncData();
}
@ -39,7 +30,7 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
description = Data.Description;
unitaryCostText = Data.UnitaryCost.ToString("G", CultureInfo.InvariantCulture);
}
CheckCommand(Data, ViewModelState);
Check();
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
@ -51,6 +42,17 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
}
}
public override void Check()
{
ModelState.Clear();
if (string.IsNullOrWhiteSpace(Data.Description))
{
ModelState.AddError("Description", Strings.NoDescription);
}
if (Data.UnitaryCost < 0) { ModelState.AddError("UnitaryCost", Strings.InvalidValue); }
if (Data.Count < 0) { ModelState.AddError("Count", Strings.InvalidValue); }
}
private int count;
public int Count
{

View File

@ -12,6 +12,7 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
using Model.Social;
using Validation;
using Model.Musical;
using System;
public class EditEstimateViewModel : EditingViewModel<Estimate>
{
@ -52,7 +53,7 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
NotifyPropertyChanged("Query");
NotifyPropertyChanged("CLient");
NotifyPropertyChanged("ModelState");
Check();
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
@ -76,6 +77,30 @@ namespace ZicMoove.ViewModels.EstimateAndBilling
NotifyPropertyChanged("ViewModelState");
}
public override void Check()
{
ModelState.Clear();
if (Data == null) return;
if (string.IsNullOrWhiteSpace(Data.Title))
ModelState.AddError("Title", "Spécifier un titre");
if (string.IsNullOrWhiteSpace(Data.Description))
ModelState.AddError("Description", "Veuillez décrire l'objet de cette facture");
if (Data.Bill==null)
ModelState.AddError("Bill", "Veuillez ajouter au moins une ligne de facture");
else
{
if (Data.Bill.Count==0)
ModelState.AddError("Bill", "Veuillez ajouter au moins une ligne de facture");
var ilc = (Bill.Count(l => !l.ModelState.IsValid));
if (ilc > 0)
{
var pluriel = (ilc > 1) ? "les lignes" : "la ligne";
ModelState.AddError("Bill", "Veuillez corriger {pluriel} de facture");
}
}
NotifyPropertyChanged("ModelState");
}
[JsonIgnore]
public ObservableCollection<string> AttachedFiles
{

View File

@ -9,16 +9,14 @@ namespace ZicMoove.ViewModels.Validation
/// Used to make the DataManager know how
/// to sync local and remote data
/// </summary>
public class EditingViewModel<DataType>: ViewModel
public abstract class EditingViewModel<DataType>: ViewModel
{
[JsonIgnore]
public Action<DataType, ModelState> CheckCommand { set; get; }
public DataType Data { get; set; }
private ModelState viewModelState = new ModelState();
private ViewModelState viewModelState = new ViewModelState();
public ModelState ViewModelState
public ViewModelState ModelState
{
get
{
@ -26,29 +24,28 @@ namespace ZicMoove.ViewModels.Validation
}
set
{
base.SetProperty<ModelState>(ref viewModelState, value);
base.SetProperty<ViewModelState>(ref viewModelState, value);
}
}
public EditingViewModel(DataType data)
{
this.Data = data;
ViewModelState = new ModelState();
ModelState = new ViewModelState();
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
Check();
}
public virtual void Check()
{
if (CheckCommand != null)
{
ViewModelState.Clear();
CheckCommand(Data, ViewModelState);
}
if (e.PropertyName != "ModelState")
Check();
}
/// <summary>
/// Must compute the ModelState property
/// from the Data one.
/// </summary>
public abstract void Check();
/* NOTE : I had a dream.
bool existsRemotely;

View File

@ -8,15 +8,15 @@ using Xamarin.Forms;
namespace ZicMoove.ViewModels.Validation
{
public class ModelState : BindableObject
public class ViewModelState : BindableObject
{
public static readonly BindableProperty IsValidProperty =
BindableProperty.Create("IsValid", typeof(bool), typeof(ModelState), false);
BindableProperty.Create("IsValid", typeof(bool), typeof(ViewModelState), false);
public static readonly BindableProperty ErrorsProperty =
BindableProperty.Create("Errors", typeof(Dictionary<string,List<InputError>>), typeof(ModelState), null);
BindableProperty.Create("Errors", typeof(Dictionary<string,List<InputError>>), typeof(ViewModelState), null);
public ModelState()
public ViewModelState()
{
Errors = new Dictionary<string, List<InputError>>();
}

View File

@ -15,5 +15,10 @@ namespace ZicMoove.ViewModels.WorkFlow
public WorkflowBookViewModel(BookQuery data) : base(data)
{
}
public override void Check()
{
throw new NotImplementedException();
}
}
}

View File

@ -104,6 +104,7 @@
<Compile Include="Model\Social\Chat\ChatStatus.cs" />
<Compile Include="Model\Social\Chat\ChatMessage.cs" />
<Compile Include="Model\Social\LocationType.cs" />
<Compile Include="Model\UI\AppEvent.cs" />
<Compile Include="Model\Workflow\Activity.cs" />
<Compile Include="Model\Workflow\CommandForm.cs" />
<Compile Include="Pages\ClientPages\ActivityPage.xaml.cs">
@ -119,8 +120,8 @@
<Compile Include="ViewModels\Messaging\ChatUserInfo.cs" />
<Compile Include="Model\Social\Chat\Connection.cs" />
<Compile Include="ViewModels\Searching\SearchingAnArtistViewModel.cs" />
<Compile Include="ViewModels\Validation\Error.cs" />
<Compile Include="ViewModels\Validation\ModelState.cs" />
<Compile Include="ViewModels\Validation\InputError.cs" />
<Compile Include="ViewModels\Validation\ViewModelState.cs" />
<Compile Include="ViewModels\PageState.cs" />
<Compile Include="Pages\EstimatePages\EstimateSigningPage.xaml.cs">
<DependentUpon>EstimateSigningPage.xaml</DependentUpon>
@ -184,7 +185,7 @@
<Compile Include="Interfaces\IMDEditor.cs" />
<Compile Include="Interfaces\IModelViewModel.cs" />
<Compile Include="Interfaces\IViewFactory.cs" />
<Compile Include="Model\ClientProviderInfo.cs" />
<Compile Include="Model\Workflow\ClientProviderInfo.cs" />
<Compile Include="Interfaces\IBookQueryData.cs" />
<Compile Include="Interfaces\IBillingLine.cs" />
<Compile Include="Interfaces\IEstimate.cs" />
@ -304,9 +305,7 @@
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="Model\UI\" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Reference Include="ExifLib, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ExifLib.PCL.1.0.1\lib\portable-net45+sl50+win+WindowsPhoneApp81+wp80+Xamarin.iOS10+MonoAndroid10+MonoTouch10\ExifLib.dll</HintPath>